2019-03-04 01:21:22 +00:00
|
|
|
import {
|
|
|
|
ACCOUNTS_STORE, DB_VERSION_SNOWFLAKE_IDS, DB_VERSION_INITIAL,
|
|
|
|
DB_VERSION_SEARCH_ACCOUNTS, META_STORE,
|
|
|
|
NOTIFICATION_TIMELINES_STORE,
|
|
|
|
NOTIFICATIONS_STORE, PINNED_STATUSES_STORE,
|
|
|
|
REBLOG_ID, RELATIONSHIPS_STORE,
|
|
|
|
STATUS_ID,
|
|
|
|
STATUS_TIMELINES_STORE,
|
|
|
|
STATUSES_STORE, THREADS_STORE,
|
|
|
|
TIMESTAMP, USERNAME_LOWERCASE
|
|
|
|
} from './constants'
|
|
|
|
import { toReversePaddedBigInt } from '../_utils/statusIdSorting'
|
|
|
|
|
|
|
|
function initialMigration (db, tx, done) {
|
|
|
|
function createObjectStore (name, init, indexes) {
|
2019-08-03 20:49:37 +00:00
|
|
|
const store = init
|
2019-03-04 01:21:22 +00:00
|
|
|
? db.createObjectStore(name, init)
|
|
|
|
: db.createObjectStore(name)
|
|
|
|
if (indexes) {
|
|
|
|
Object.keys(indexes).forEach(indexKey => {
|
|
|
|
store.createIndex(indexKey, indexes[indexKey])
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
createObjectStore(STATUSES_STORE, { keyPath: 'id' }, {
|
|
|
|
[TIMESTAMP]: TIMESTAMP,
|
|
|
|
[REBLOG_ID]: REBLOG_ID
|
|
|
|
})
|
|
|
|
createObjectStore(STATUS_TIMELINES_STORE, null, {
|
2019-08-03 20:49:37 +00:00
|
|
|
statusId: ''
|
2019-03-04 01:21:22 +00:00
|
|
|
})
|
|
|
|
createObjectStore(NOTIFICATIONS_STORE, { keyPath: 'id' }, {
|
|
|
|
[TIMESTAMP]: TIMESTAMP,
|
|
|
|
[STATUS_ID]: STATUS_ID
|
|
|
|
})
|
|
|
|
createObjectStore(NOTIFICATION_TIMELINES_STORE, null, {
|
2019-08-03 20:49:37 +00:00
|
|
|
notificationId: ''
|
2019-03-04 01:21:22 +00:00
|
|
|
})
|
|
|
|
createObjectStore(ACCOUNTS_STORE, { keyPath: 'id' }, {
|
|
|
|
[TIMESTAMP]: TIMESTAMP
|
|
|
|
})
|
|
|
|
createObjectStore(RELATIONSHIPS_STORE, { keyPath: 'id' }, {
|
|
|
|
[TIMESTAMP]: TIMESTAMP
|
|
|
|
})
|
|
|
|
createObjectStore(THREADS_STORE, null, {
|
2019-08-03 20:49:37 +00:00
|
|
|
statusId: ''
|
2019-03-04 01:21:22 +00:00
|
|
|
})
|
|
|
|
createObjectStore(PINNED_STATUSES_STORE, null, {
|
2019-08-03 20:49:37 +00:00
|
|
|
statusId: ''
|
2019-03-04 01:21:22 +00:00
|
|
|
})
|
|
|
|
createObjectStore(META_STORE)
|
|
|
|
done()
|
|
|
|
}
|
|
|
|
|
|
|
|
function addSearchAccountsMigration (db, tx, done) {
|
|
|
|
tx.objectStore(ACCOUNTS_STORE)
|
|
|
|
.createIndex(USERNAME_LOWERCASE, USERNAME_LOWERCASE)
|
|
|
|
done()
|
|
|
|
}
|
|
|
|
|
|
|
|
function snowflakeIdsMigration (db, tx, done) {
|
2019-08-03 20:49:37 +00:00
|
|
|
const stores = [STATUS_TIMELINES_STORE, NOTIFICATION_TIMELINES_STORE]
|
2019-03-04 01:21:22 +00:00
|
|
|
let storeDoneCount = 0
|
|
|
|
|
|
|
|
// Here we have to convert the old "reversePaddedBigInt" format to the new
|
|
|
|
// one which is compatible with Pleroma-style snowflake IDs.
|
|
|
|
stores.forEach(store => {
|
2019-08-03 20:49:37 +00:00
|
|
|
const objectStore = tx.objectStore(store)
|
|
|
|
const cursor = objectStore.openCursor()
|
2019-03-04 01:21:22 +00:00
|
|
|
cursor.onsuccess = e => {
|
2019-08-03 20:49:37 +00:00
|
|
|
const { result } = e.target
|
2019-03-04 01:21:22 +00:00
|
|
|
if (result) {
|
2019-08-03 20:49:37 +00:00
|
|
|
const { key, value } = result
|
2019-03-04 01:21:22 +00:00
|
|
|
// key is timeline name plus delimiter plus reverse padded big int
|
2019-08-03 20:49:37 +00:00
|
|
|
const newKey = key.split('\u0000')[0] + '\u0000' + toReversePaddedBigInt(value)
|
2019-03-04 01:21:22 +00:00
|
|
|
|
|
|
|
objectStore.delete(key).onsuccess = () => {
|
|
|
|
objectStore.add(value, newKey).onsuccess = () => {
|
|
|
|
result.continue()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (++storeDoneCount === stores.length) {
|
|
|
|
done()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
export const migrations = [
|
|
|
|
{
|
|
|
|
version: DB_VERSION_INITIAL,
|
|
|
|
migration: initialMigration
|
|
|
|
},
|
|
|
|
{
|
|
|
|
version: DB_VERSION_SEARCH_ACCOUNTS,
|
|
|
|
migration: addSearchAccountsMigration
|
|
|
|
},
|
|
|
|
{
|
|
|
|
version: DB_VERSION_SNOWFLAKE_IDS,
|
|
|
|
migration: snowflakeIdsMigration
|
|
|
|
}
|
|
|
|
]
|