| @@ -4,14 +4,23 @@ class app.DB · 3 unmodified lines |
| 4 | constructor: -> | 4 | constructor: -> |
| 5 | @useIndexedDB = @useIndexedDB() | 5 | @useIndexedDB = @useIndexedDB() |
| 6 | | 6 | |
| 7 | init: (@_callback) -> | 7 | db: (fn) -> |
| 8 | if @useIndexedDB | 8 | return fn @_db unless @useIndexedDB and @_db is undefined |
| 9 | @initIndexedDB() | 9 | |
| 10 | else | 10 | if @callback isnt undefined |
| 11 | @callback() | 11 | _callback = @callback |
| 12 | return | 12 | @callback = => |
| | 13 | _callback() |
| | 14 | fn @_db |
| | 15 | return |
| | 16 | return |
| | 17 | |
| | 18 | @callback = => |
| | 19 | @_db ?= false |
| | 20 | delete @callback |
| | 21 | fn @_db |
| | 22 | return |
| 13 | | 23 | |
| 14 | initIndexedDB: -> | | |
| 15 | try | 24 | try |
| 16 | req = indexedDB.open(NAME, @indexedDBVersion()) | 25 | req = indexedDB.open(NAME, @indexedDBVersion()) |
| 17 | req.onerror = @callback | 26 | req.onerror = @callback |
| @@ -21,20 +30,12 @@ class app.DB · 3 unmodified lines |
| 21 | @callback() | 30 | @callback() |
| 22 | return | 31 | return |
| 23 | | 32 | |
| 24 | isEnabled: -> | | |
| 25 | !!@db | | |
| 26 | | | |
| 27 | callback: => | | |
| 28 | @_callback?() | | |
| 29 | @_callback = null | | |
| 30 | return | | |
| 31 | | | |
| 32 | onOpenSuccess: (event) => | 33 | onOpenSuccess: (event) => |
| 33 | try | 34 | try |
| 34 | @db = event.target.result | 35 | @_db = event.target.result |
| 35 | @db.transaction(['docs', app.docs.all()[0].slug], 'readwrite').abort() # https://bugs.webkit.org/show_bug.cgi?id=136937 | 36 | @_db.transaction(['docs', app.docs.all()[0].slug], 'readwrite').abort() # https://bugs.webkit.org/show_bug.cgi?id=136937 |
| 36 | catch | 37 | catch |
| 37 | @db = null | 38 | @_db = false |
| 38 | | 39 | |
| 39 | @callback() | 40 | @callback() |
| 40 | return | 41 | return |
| @@ -53,43 +54,61 @@ class app.DB · 12 unmodified lines |
| 53 | return | 54 | return |
| 54 | | 55 | |
| 55 | store: (doc, data, onSuccess, onError) -> | 56 | store: (doc, data, onSuccess, onError) -> |
| 56 | txn = @db.transaction ['docs', doc.slug], 'readwrite' | 57 | @db (db) -> |
| 57 | txn.oncomplete = -> if txn.error then onError() else onSuccess() | 58 | unless db |
| | 59 | onError() |
| | 60 | return |
| | 61 | |
| | 62 | txn = db.transaction ['docs', doc.slug], 'readwrite' |
| | 63 | txn.oncomplete = -> if txn.error then onError() else onSuccess() |
| 58 | | 64 | |
| 59 | store = txn.objectStore(doc.slug) | 65 | store = txn.objectStore(doc.slug) |
| 60 | store.clear() | 66 | store.clear() |
| 61 | store.add(content, path) for path, content of data | 67 | store.add(content, path) for path, content of data |
| 62 | | 68 | |
| 63 | store = txn.objectStore('docs') | 69 | store = txn.objectStore('docs') |
| 64 | store.put(doc.mtime, doc.slug) | 70 | store.put(doc.mtime, doc.slug) |
| | 71 | return |
| 65 | return | 72 | return |
| 66 | | 73 | |
| 67 | unstore: (doc, onSuccess, onError) -> | 74 | unstore: (doc, onSuccess, onError) -> |
| 68 | txn = @db.transaction ['docs', doc.slug], 'readwrite' | 75 | @db (db) -> |
| 69 | txn.oncomplete = -> if txn.error then onError() else onSuccess() | 76 | unless db |
| | 77 | onError() |
| | 78 | return |
| | 79 | |
| | 80 | txn = db.transaction ['docs', doc.slug], 'readwrite' |
| | 81 | txn.oncomplete = -> if txn.error then onError() else onSuccess() |
| 70 | | 82 | |
| 71 | store = txn.objectStore(doc.slug) | 83 | store = txn.objectStore(doc.slug) |
| 72 | store.clear() | 84 | store.clear() |
| 73 | | 85 | |
| 74 | store = txn.objectStore('docs') | 86 | store = txn.objectStore('docs') |
| 75 | store.delete(doc.slug) | 87 | store.delete(doc.slug) |
| | 88 | return |
| 76 | return | 89 | return |
| 77 | | 90 | |
| 78 | version: (doc, callback) -> | 91 | version: (doc, fn) -> |
| 79 | txn = @db.transaction ['docs'], 'readonly' | 92 | @db (db) -> |
| 80 | store = txn.objectStore('docs') | 93 | unless db |
| | 94 | fn(false) |
| | 95 | return |
| 81 | | 96 | |
| 82 | req = store.get(doc.slug) | 97 | txn = db.transaction ['docs'], 'readonly' |
| 83 | req.onsuccess = -> callback(!!req.result) | 98 | store = txn.objectStore('docs') |
| 84 | req.onerror = -> callback(false) | 99 | |
| | 100 | req = store.get(doc.slug) |
| | 101 | req.onsuccess = -> fn(!!req.result) |
| | 102 | req.onerror = -> fn(false) |
| | 103 | return |
| 85 | return | 104 | return |
| 86 | | 105 | |
| 87 | load: (entry, onSuccess, onError) -> | 106 | load: (entry, onSuccess, onError) -> |
| 88 | if @isEnabled() | 107 | if @useIndexedDB and @_db isnt false |
| 89 | onError = @loadWithXHR.bind(@, entry, onSuccess, onError) | 108 | onError = @loadWithXHR.bind(@, entry, onSuccess, onError) |
| 90 | @loadWithIDB(entry, onSuccess, onError) | 109 | @loadWithIDB entry, onSuccess, onError |
| 91 | else | 110 | else |
| 92 | @loadWithXHR(entry, onSuccess, onError) | 111 | @loadWithXHR entry, onSuccess, onError |
| 93 | | 112 | |
| 94 | loadWithXHR: (entry, onSuccess, onError) -> | 113 | loadWithXHR: (entry, onSuccess, onError) -> |
| 95 | ajax | 114 | ajax |
| @@ -99,14 +118,19 @@ class app.DB · 3 unmodified lines |
| 99 | error: onError | 118 | error: onError |
| 100 | | 119 | |
| 101 | loadWithIDB: (entry, onSuccess, onError) -> | 120 | loadWithIDB: (entry, onSuccess, onError) -> |
| 102 | txn = @db.transaction [entry.doc.slug], 'readonly' | 121 | @db (db) -> |
| 103 | store = txn.objectStore(entry.doc.slug) | 122 | unless db |
| | 123 | onError() |
| | 124 | return |
| | 125 | |
| | 126 | txn = db.transaction [entry.doc.slug], 'readonly' |
| | 127 | store = txn.objectStore(entry.doc.slug) |
| 104 | | 128 | |
| 105 | req = store.get(entry.path) | 129 | req = store.get(entry.path) |
| 106 | req.onsuccess = -> if req.result then onSuccess(req.result) else onError() | 130 | req.onsuccess = -> if req.result then onSuccess(req.result) else onError() |
| 107 | req.onerror = onError | 131 | req.onerror = onError |
| 108 | | 132 | |
| 109 | txn | 133 | txn |
| 110 | | 134 | |
| 111 | reset: -> | 135 | reset: -> |
| 112 | try indexedDB?.deleteDatabase(NAME) catch | 136 | try indexedDB?.deleteDatabase(NAME) catch |