diff --git a/routes/_database/cleanup.js b/routes/_database/cleanup.js index 3f4f2831..af6fa43c 100644 --- a/routes/_database/cleanup.js +++ b/routes/_database/cleanup.js @@ -4,6 +4,7 @@ import { ACCOUNTS_STORE, NOTIFICATION_TIMELINES_STORE, NOTIFICATIONS_STORE, + PINNED_STATUSES_STORE, RELATIONSHIPS_STORE, STATUS_TIMELINES_STORE, STATUSES_STORE, @@ -38,11 +39,11 @@ function cleanupStatuses (statusesStore, statusTimelinesStore, threadsStore, cut results.forEach(result => { statusesStore.delete(result.id) threadsStore.delete(result.id) - let req = statusTimelinesStore.index('statusId').getAll(IDBKeyRange.only(result.id)) + let req = statusTimelinesStore.index('statusId').getAllKeys(IDBKeyRange.only(result.id)) req.onsuccess = e => { - let results = e.target.result - results.forEach(result => { - statusTimelinesStore.delete(result.id) + let keys = e.target.result + keys.forEach(key => { + statusTimelinesStore.delete(key) }) } }) @@ -56,11 +57,11 @@ function cleanupNotifications (notificationsStore, notificationTimelinesStore, c results => { results.forEach(result => { notificationsStore.delete(result.id) - let req = notificationTimelinesStore.index('notificationId').getAll(IDBKeyRange.only(result.id)) + let req = notificationTimelinesStore.index('notificationId').getAllKeys(IDBKeyRange.only(result.id)) req.onsuccess = e => { - let results = e.target.result - results.forEach(result => { - notificationTimelinesStore.delete(result.id) + let keys = e.target.result + keys.forEach(key => { + notificationTimelinesStore.delete(key) }) } }) @@ -68,12 +69,20 @@ function cleanupNotifications (notificationsStore, notificationTimelinesStore, c ) } -function cleanupAccounts (accountsStore, cutoff) { +function cleanupAccounts (accountsStore, pinnedStatusesStore, cutoff) { batchedGetAll( () => accountsStore.index(TIMESTAMP).getAll(IDBKeyRange.upperBound(cutoff), BATCH_SIZE), (results) => { results.forEach(result => { accountsStore.delete(result.id) + let keyRange = IDBKeyRange.bound(result.id + '\u0000', result.id + '\u0000\uffff') + let req = pinnedStatusesStore.getAllKeys(keyRange) + req.onsuccess = e => { + let keys = e.target.result + keys.forEach(key => { + pinnedStatusesStore.delete(key) + }) + } }) } ) @@ -101,7 +110,8 @@ async function cleanup (instanceName) { NOTIFICATION_TIMELINES_STORE, ACCOUNTS_STORE, RELATIONSHIPS_STORE, - THREADS_STORE + THREADS_STORE, + PINNED_STATUSES_STORE ] await dbPromise(db, storeNames, 'readwrite', (stores) => { let [ @@ -111,14 +121,15 @@ async function cleanup (instanceName) { notificationTimelinesStore, accountsStore, relationshipsStore, - threadsStore + threadsStore, + pinnedStatusesStore ] = stores let cutoff = Date.now() - TIME_AGO cleanupStatuses(statusesStore, statusTimelinesStore, threadsStore, cutoff) cleanupNotifications(notificationsStore, notificationTimelinesStore, cutoff) - cleanupAccounts(accountsStore, cutoff) + cleanupAccounts(accountsStore, pinnedStatusesStore, cutoff) cleanupRelationships(relationshipsStore, cutoff) }) stop(`cleanup:${instanceName}`) diff --git a/routes/_database/constants.js b/routes/_database/constants.js index f7ec6654..f148722b 100644 --- a/routes/_database/constants.js +++ b/routes/_database/constants.js @@ -1,12 +1,12 @@ -export const STATUSES_STORE = 'statuses' -export const STATUS_TIMELINES_STORE = 'status_timelines' -export const META_STORE = 'meta' -export const ACCOUNTS_STORE = 'accounts' -export const RELATIONSHIPS_STORE = 'relationships' -export const NOTIFICATIONS_STORE = 'notifications' -export const NOTIFICATION_TIMELINES_STORE = 'notification_timelines' -export const PINNED_STATUSES_STORE = 'pinned_statuses' -export const THREADS_STORE = 'threads' +export const STATUSES_STORE = 'statuses-v1' +export const STATUS_TIMELINES_STORE = 'status_timelines-v1' +export const META_STORE = 'meta-v1' +export const ACCOUNTS_STORE = 'accounts-v1' +export const RELATIONSHIPS_STORE = 'relationships-v1' +export const NOTIFICATIONS_STORE = 'notifications-v1' +export const NOTIFICATION_TIMELINES_STORE = 'notification_timelines-v1' +export const PINNED_STATUSES_STORE = 'pinned_statuses-v1' +export const THREADS_STORE = 'threads-v1' export const TIMESTAMP = '__pinafore_ts' export const ACCOUNT_ID = '__pinafore_acct_id' diff --git a/routes/_database/databaseLifecycle.js b/routes/_database/databaseLifecycle.js index 095b3cbb..7c7d4d7e 100644 --- a/routes/_database/databaseLifecycle.js +++ b/routes/_database/databaseLifecycle.js @@ -7,13 +7,15 @@ import { NOTIFICATIONS_STORE, NOTIFICATION_TIMELINES_STORE, PINNED_STATUSES_STORE, - TIMESTAMP, REBLOG_ID, THREADS_STORE + TIMESTAMP, + REBLOG_ID, + THREADS_STORE } from './constants' const openReqs = {} const databaseCache = {} -const DB_VERSION = 4 +const DB_VERSION = 5 export function getDatabase (instanceName) { if (!instanceName) { @@ -33,30 +35,24 @@ export function getDatabase (instanceName) { req.onupgradeneeded = (e) => { let db = req.result let tx = e.currentTarget.transaction - if (e.oldVersion < 1) { + if (e.oldVersion < 5) { db.createObjectStore(STATUSES_STORE, {keyPath: 'id'}) .createIndex(TIMESTAMP, TIMESTAMP) - db.createObjectStore(STATUS_TIMELINES_STORE, {keyPath: 'id'}) - .createIndex('statusId', 'statusId') + db.createObjectStore(STATUS_TIMELINES_STORE) + .createIndex('statusId', '') db.createObjectStore(NOTIFICATIONS_STORE, {keyPath: 'id'}) .createIndex(TIMESTAMP, TIMESTAMP) - db.createObjectStore(NOTIFICATION_TIMELINES_STORE, {keyPath: 'id'}) - .createIndex('notificationId', 'notificationId') + db.createObjectStore(NOTIFICATION_TIMELINES_STORE) + .createIndex('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) { + db.createObjectStore(META_STORE) + db.createObjectStore(PINNED_STATUSES_STORE) tx.objectStore(STATUSES_STORE).createIndex(REBLOG_ID, REBLOG_ID) - } - if (e.oldVersion < 3) { tx.objectStore(NOTIFICATIONS_STORE).createIndex('statusId', 'statusId') - } - if (e.oldVersion < 4) { - db.createObjectStore(THREADS_STORE, {keyPath: 'id'}) + db.createObjectStore(THREADS_STORE) } } req.onsuccess = () => resolve(req.result) diff --git a/routes/_database/meta.js b/routes/_database/meta.js index 88615a8a..9c48ea04 100644 --- a/routes/_database/meta.js +++ b/routes/_database/meta.js @@ -9,7 +9,7 @@ async function getMetaProperty (instanceName, key) { const db = await getDatabase(instanceName) let result = await dbPromise(db, META_STORE, 'readonly', (store, callback) => { store.get(key).onsuccess = (e) => { - callback(e.target.result && e.target.result.value) + callback(e.target.result) } }) setInCache(metaCache, instanceName, key, result) @@ -20,10 +20,7 @@ async function setMetaProperty (instanceName, key, value) { setInCache(metaCache, instanceName, key, value) const db = await getDatabase(instanceName) return dbPromise(db, META_STORE, 'readwrite', (store) => { - store.put({ - key: key, - value: value - }) + store.put(value, key) }) } diff --git a/routes/_database/timelines.js b/routes/_database/timelines.js index b2a77872..119996a8 100644 --- a/routes/_database/timelines.js +++ b/routes/_database/timelines.js @@ -46,8 +46,8 @@ async function getNotificationTimeline (instanceName, timeline, maxId, limit) { timelineStore.getAll(keyRange, limit).onsuccess = e => { let timelineResults = e.target.result let res = new Array(timelineResults.length) - timelineResults.forEach((timelineResult, i) => { - fetchNotification(notificationsStore, statusesStore, accountsStore, timelineResult.notificationId, notification => { + timelineResults.forEach((notificationId, i) => { + fetchNotification(notificationsStore, statusesStore, accountsStore, notificationId, notification => { res[i] = notification }) }) @@ -65,8 +65,8 @@ async function getStatusTimeline (instanceName, timeline, maxId, limit) { getReq.onsuccess = e => { let timelineResults = e.target.result let res = new Array(timelineResults.length) - timelineResults.forEach((timelineResult, i) => { - fetchStatus(statusesStore, accountsStore, timelineResult.statusId, status => { + timelineResults.forEach((statusId, i) => { + fetchStatus(statusesStore, accountsStore, statusId, status => { res[i] = status }) }) @@ -81,7 +81,7 @@ async function getStatusThread (instanceName, statusId) { return dbPromise(db, storeNames, 'readonly', (stores, callback) => { let [ threadsStore, statusesStore, accountsStore ] = stores threadsStore.get(statusId).onsuccess = e => { - let thread = e.target.result.thread + let thread = e.target.result let res = new Array(thread.length) thread.forEach((otherStatusId, i) => { fetchStatus(statusesStore, accountsStore, otherStatusId, status => { @@ -196,10 +196,7 @@ async function insertTimelineNotifications (instanceName, timeline, notification let [ timelineStore, notificationsStore, accountsStore, statusesStore ] = stores for (let notification of notifications) { storeNotification(notificationsStore, statusesStore, accountsStore, notification) - timelineStore.put({ - id: createTimelineId(timeline, notification.id), - notificationId: notification.id - }) + timelineStore.put(notification.id, createTimelineId(timeline, notification.id)) } }) } @@ -214,10 +211,7 @@ async function insertTimelineStatuses (instanceName, timeline, statuses) { let [ timelineStore, statusesStore, accountsStore ] = stores for (let status of statuses) { storeStatus(statusesStore, accountsStore, status) - timelineStore.put({ - id: createTimelineId(timeline, status.id), - statusId: status.id - }) + timelineStore.put(status.id, createTimelineId(timeline, status.id)) } }) } @@ -230,10 +224,7 @@ async function insertStatusThread (instanceName, statusId, statuses) { let storeNames = [THREADS_STORE, STATUSES_STORE, ACCOUNTS_STORE] await dbPromise(db, storeNames, 'readwrite', (stores) => { let [ threadsStore, statusesStore, accountsStore ] = stores - threadsStore.put({ - id: statusId, - thread: statuses.map(_ => _.id) - }) + threadsStore.put(statuses.map(_ => _.id), statusId) for (let status of statuses) { storeStatus(statusesStore, accountsStore, status) } @@ -374,10 +365,7 @@ export async function insertPinnedStatuses (instanceName, accountId, statuses) { let [ pinnedStatusesStore, statusesStore, accountsStore ] = stores statuses.forEach((status, i) => { storeStatus(statusesStore, accountsStore, status) - pinnedStatusesStore.put({ - id: accountId + '\u0000' + toPaddedBigInt(i), - statusId: status.id - }) + pinnedStatusesStore.put(status.id, accountId + '\u0000' + toPaddedBigInt(i)) }) }) } @@ -394,8 +382,8 @@ export async function getPinnedStatuses (instanceName, accountId) { pinnedStatusesStore.getAll(keyRange).onsuccess = e => { let pinnedResults = e.target.result let res = new Array(pinnedResults.length) - pinnedResults.forEach((pinnedResult, i) => { - fetchStatus(statusesStore, accountsStore, pinnedResult.statusId, status => { + pinnedResults.forEach((statusId, i) => { + fetchStatus(statusesStore, accountsStore, statusId, status => { res[i] = status }) })