semaphore/routes/_database/databaseLifecycle.js

97 lines
3.0 KiB
JavaScript
Raw Normal View History

2018-01-23 17:03:31 +00:00
import {
META_STORE,
STATUS_TIMELINES_STORE,
2018-01-23 17:21:21 +00:00
STATUSES_STORE,
2018-01-28 20:51:48 +00:00
ACCOUNTS_STORE,
RELATIONSHIPS_STORE,
NOTIFICATIONS_STORE,
2018-02-11 18:35:25 +00:00
NOTIFICATION_TIMELINES_STORE,
2018-02-14 03:34:37 +00:00
PINNED_STATUSES_STORE,
2018-03-09 02:31:59 +00:00
TIMESTAMP, REBLOG_ID, THREADS_STORE
2018-01-23 17:03:31 +00:00
} from './constants'
2018-02-09 06:29:29 +00:00
const openReqs = {}
const databaseCache = {}
2018-03-09 02:31:59 +00:00
const DB_VERSION = 4
2018-02-14 03:34:37 +00:00
2018-02-09 06:29:29 +00:00
export function getDatabase (instanceName) {
2018-01-27 16:22:23 +00:00
if (!instanceName) {
2018-01-25 08:01:56 +00:00
throw new Error('instanceName is undefined in getDatabase()')
}
2018-01-23 17:03:31 +00:00
if (databaseCache[instanceName]) {
return Promise.resolve(databaseCache[instanceName])
}
databaseCache[instanceName] = new Promise((resolve, reject) => {
2018-01-28 20:51:48 +00:00
let req = indexedDB.open(instanceName, DB_VERSION)
2018-01-23 17:03:31 +00:00
openReqs[instanceName] = req
req.onerror = reject
req.onblocked = () => {
console.log('idb blocked')
}
2018-01-28 20:51:48 +00:00
req.onupgradeneeded = (e) => {
2018-02-09 06:29:29 +00:00
let db = req.result
2018-02-17 03:38:21 +00:00
let tx = e.currentTarget.transaction
if (e.oldVersion < 1) {
db.createObjectStore(STATUSES_STORE, {keyPath: 'id'})
.createIndex(TIMESTAMP, TIMESTAMP)
db.createObjectStore(STATUS_TIMELINES_STORE, {keyPath: 'id'})
.createIndex('statusId', 'statusId')
db.createObjectStore(NOTIFICATIONS_STORE, {keyPath: 'id'})
.createIndex(TIMESTAMP, TIMESTAMP)
db.createObjectStore(NOTIFICATION_TIMELINES_STORE, {keyPath: 'id'})
.createIndex('notificationId', 'notificationId')
db.createObjectStore(ACCOUNTS_STORE, {keyPath: 'id'})
.createIndex(TIMESTAMP, TIMESTAMP)
db.createObjectStore(RELATIONSHIPS_STORE, {keyPath: 'id'})
.createIndex(TIMESTAMP, TIMESTAMP)
db.createObjectStore(META_STORE, {keyPath: 'key'})
db.createObjectStore(PINNED_STATUSES_STORE, {keyPath: 'id'})
}
if (e.oldVersion < 2) {
tx.objectStore(STATUSES_STORE).createIndex(REBLOG_ID, REBLOG_ID)
}
if (e.oldVersion < 3) {
tx.objectStore(NOTIFICATIONS_STORE).createIndex('statusId', 'statusId')
}
2018-03-09 02:31:59 +00:00
if (e.oldVersion < 4) {
db.createObjectStore(THREADS_STORE, {keyPath: 'id'})
}
2018-01-23 17:03:31 +00:00
}
req.onsuccess = () => resolve(req.result)
})
return databaseCache[instanceName]
}
2018-02-09 06:29:29 +00:00
export async function dbPromise (db, storeName, readOnlyOrReadWrite, cb) {
return new Promise((resolve, reject) => {
2018-01-23 17:03:31 +00:00
const tx = db.transaction(storeName, readOnlyOrReadWrite)
2018-02-09 06:29:29 +00:00
let store = typeof storeName === 'string'
? tx.objectStore(storeName)
: storeName.map(name => tx.objectStore(name))
2018-01-23 17:03:31 +00:00
let res
cb(store, (result) => {
res = result
})
tx.oncomplete = () => resolve(res)
2018-02-09 06:29:29 +00:00
tx.onerror = () => reject(tx.error)
2018-01-23 17:03:31 +00:00
})
}
2018-02-09 06:29:29 +00:00
export function deleteDatabase (instanceName) {
2018-01-23 17:03:31 +00:00
return new Promise((resolve, reject) => {
// close any open requests
2018-02-09 06:29:29 +00:00
let openReq = openReqs[instanceName]
2018-01-23 17:03:31 +00:00
if (openReq && openReq.result) {
openReq.result.close()
}
delete openReqs[instanceName]
delete databaseCache[instanceName]
let req = indexedDB.deleteDatabase(instanceName)
req.onsuccess = () => resolve()
2018-02-09 06:29:29 +00:00
req.onerror = () => reject(req.error)
2018-01-23 17:03:31 +00:00
})
2018-02-09 06:29:29 +00:00
}