2018-01-23 09:03:31 -08:00
|
|
|
import {
|
|
|
|
META_STORE,
|
2018-02-03 18:06:02 -08:00
|
|
|
STATUS_TIMELINES_STORE,
|
2018-01-23 09:21:21 -08:00
|
|
|
STATUSES_STORE,
|
2018-01-28 12:51:48 -08:00
|
|
|
ACCOUNTS_STORE,
|
2018-02-03 18:06:02 -08:00
|
|
|
RELATIONSHIPS_STORE,
|
|
|
|
NOTIFICATIONS_STORE,
|
2018-02-11 10:35:25 -08:00
|
|
|
NOTIFICATION_TIMELINES_STORE,
|
2018-02-13 19:34:37 -08:00
|
|
|
PINNED_STATUSES_STORE,
|
2018-03-08 23:18:18 -08:00
|
|
|
TIMESTAMP,
|
|
|
|
REBLOG_ID,
|
2018-03-10 16:21:10 -08:00
|
|
|
THREADS_STORE,
|
2018-03-24 18:04:54 -07:00
|
|
|
STATUS_ID,
|
|
|
|
USERNAME_LOWERCASE
|
2018-01-23 09:03:31 -08:00
|
|
|
} from './constants'
|
2018-08-29 19:03:12 -07:00
|
|
|
import { addKnownInstance, deleteKnownInstance } from './knownInstances'
|
2018-01-23 09:03:31 -08:00
|
|
|
|
2018-09-05 21:08:38 -07:00
|
|
|
if (process.browser) {
|
|
|
|
require('indexeddb-getall-shim') // needed for Edge
|
|
|
|
}
|
|
|
|
|
2018-02-08 22:29:29 -08:00
|
|
|
const openReqs = {}
|
|
|
|
const databaseCache = {}
|
|
|
|
|
2018-03-24 18:04:54 -07:00
|
|
|
const DB_VERSION_INITIAL = 9
|
|
|
|
const DB_VERSION_SEARCH_ACCOUNTS = 10
|
|
|
|
const DB_VERSION_CURRENT = 10
|
2018-02-13 19:34:37 -08:00
|
|
|
|
2018-09-05 19:52:51 -07:00
|
|
|
function createDatabase (instanceName) {
|
|
|
|
return new Promise((resolve, reject) => {
|
2018-03-24 18:04:54 -07:00
|
|
|
let req = indexedDB.open(instanceName, DB_VERSION_CURRENT)
|
2018-01-23 09:03:31 -08:00
|
|
|
openReqs[instanceName] = req
|
|
|
|
req.onerror = reject
|
|
|
|
req.onblocked = () => {
|
|
|
|
console.log('idb blocked')
|
|
|
|
}
|
2018-01-28 12:51:48 -08:00
|
|
|
req.onupgradeneeded = (e) => {
|
2018-02-08 22:29:29 -08:00
|
|
|
let db = req.result
|
2018-03-24 18:04:54 -07:00
|
|
|
let tx = e.currentTarget.transaction
|
2018-03-10 20:24:07 -08:00
|
|
|
|
|
|
|
function createObjectStore (name, init, indexes) {
|
|
|
|
let store = init
|
|
|
|
? db.createObjectStore(name, init)
|
|
|
|
: db.createObjectStore(name)
|
|
|
|
if (indexes) {
|
2018-04-17 21:47:39 -07:00
|
|
|
Object.keys(indexes).forEach(indexKey => {
|
|
|
|
store.createIndex(indexKey, indexes[indexKey])
|
2018-03-10 20:24:07 -08:00
|
|
|
})
|
|
|
|
}
|
2018-03-08 18:31:59 -08:00
|
|
|
}
|
2018-03-10 20:24:07 -08:00
|
|
|
|
2018-03-24 18:04:54 -07:00
|
|
|
if (e.oldVersion < DB_VERSION_INITIAL) {
|
2018-08-29 21:42:57 -07:00
|
|
|
createObjectStore(STATUSES_STORE, { keyPath: 'id' }, {
|
2018-03-10 20:24:07 -08:00
|
|
|
[TIMESTAMP]: TIMESTAMP,
|
|
|
|
[REBLOG_ID]: REBLOG_ID
|
|
|
|
})
|
|
|
|
createObjectStore(STATUS_TIMELINES_STORE, null, {
|
|
|
|
'statusId': ''
|
|
|
|
})
|
2018-08-29 21:42:57 -07:00
|
|
|
createObjectStore(NOTIFICATIONS_STORE, { keyPath: 'id' }, {
|
2018-03-10 20:24:07 -08:00
|
|
|
[TIMESTAMP]: TIMESTAMP,
|
|
|
|
[STATUS_ID]: STATUS_ID
|
|
|
|
})
|
|
|
|
createObjectStore(NOTIFICATION_TIMELINES_STORE, null, {
|
|
|
|
'notificationId': ''
|
|
|
|
})
|
2018-08-29 21:42:57 -07:00
|
|
|
createObjectStore(ACCOUNTS_STORE, { keyPath: 'id' }, {
|
2018-03-10 20:24:07 -08:00
|
|
|
[TIMESTAMP]: TIMESTAMP
|
|
|
|
})
|
2018-08-29 21:42:57 -07:00
|
|
|
createObjectStore(RELATIONSHIPS_STORE, { keyPath: 'id' }, {
|
2018-03-10 20:24:07 -08:00
|
|
|
[TIMESTAMP]: TIMESTAMP
|
|
|
|
})
|
|
|
|
createObjectStore(THREADS_STORE, null, {
|
|
|
|
'statusId': ''
|
|
|
|
})
|
|
|
|
createObjectStore(PINNED_STATUSES_STORE, null, {
|
|
|
|
'statusId': ''
|
|
|
|
})
|
|
|
|
createObjectStore(META_STORE)
|
2018-03-10 16:21:10 -08:00
|
|
|
}
|
2018-03-24 18:04:54 -07:00
|
|
|
if (e.oldVersion < DB_VERSION_SEARCH_ACCOUNTS) {
|
|
|
|
tx.objectStore(ACCOUNTS_STORE)
|
|
|
|
.createIndex(USERNAME_LOWERCASE, USERNAME_LOWERCASE)
|
|
|
|
}
|
2018-01-23 09:03:31 -08:00
|
|
|
}
|
|
|
|
req.onsuccess = () => resolve(req.result)
|
|
|
|
})
|
2018-09-05 19:52:51 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
export async function getDatabase (instanceName) {
|
|
|
|
if (!instanceName) {
|
|
|
|
throw new Error('instanceName is undefined in getDatabase()')
|
|
|
|
}
|
|
|
|
if (!databaseCache[instanceName]) {
|
|
|
|
databaseCache[instanceName] = await createDatabase(instanceName)
|
|
|
|
await addKnownInstance(instanceName)
|
|
|
|
}
|
2018-01-23 09:03:31 -08:00
|
|
|
return databaseCache[instanceName]
|
|
|
|
}
|
|
|
|
|
2018-02-08 22:29:29 -08:00
|
|
|
export async function dbPromise (db, storeName, readOnlyOrReadWrite, cb) {
|
|
|
|
return new Promise((resolve, reject) => {
|
2018-01-23 09:03:31 -08:00
|
|
|
const tx = db.transaction(storeName, readOnlyOrReadWrite)
|
2018-02-08 22:29:29 -08:00
|
|
|
let store = typeof storeName === 'string'
|
|
|
|
? tx.objectStore(storeName)
|
|
|
|
: storeName.map(name => tx.objectStore(name))
|
2018-01-23 09:03:31 -08:00
|
|
|
let res
|
|
|
|
cb(store, (result) => {
|
|
|
|
res = result
|
|
|
|
})
|
|
|
|
|
|
|
|
tx.oncomplete = () => resolve(res)
|
2018-02-08 22:29:29 -08:00
|
|
|
tx.onerror = () => reject(tx.error)
|
2018-01-23 09:03:31 -08:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2018-02-08 22:29:29 -08:00
|
|
|
export function deleteDatabase (instanceName) {
|
2018-01-23 09:03:31 -08:00
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
// close any open requests
|
2018-02-08 22:29:29 -08:00
|
|
|
let openReq = openReqs[instanceName]
|
2018-01-23 09:03:31 -08:00
|
|
|
if (openReq && openReq.result) {
|
|
|
|
openReq.result.close()
|
|
|
|
}
|
|
|
|
delete openReqs[instanceName]
|
|
|
|
delete databaseCache[instanceName]
|
|
|
|
let req = indexedDB.deleteDatabase(instanceName)
|
|
|
|
req.onsuccess = () => resolve()
|
2018-02-08 22:29:29 -08:00
|
|
|
req.onerror = () => reject(req.error)
|
2018-08-29 19:03:12 -07:00
|
|
|
}).then(() => deleteKnownInstance(instanceName))
|
2018-02-08 22:29:29 -08:00
|
|
|
}
|