Merge pull request #3001 from h3poteto/marker/loki

Use lokijs instead of nedb for marker database
This commit is contained in:
AkiraFukushima 2021-12-29 16:46:40 +09:00 committed by GitHub
commit 49b2f678d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 90 additions and 34 deletions

View File

@ -87,6 +87,7 @@
"emoji-mart-vue": "^2.6.6", "emoji-mart-vue": "^2.6.6",
"i18next": "^21.3.3", "i18next": "^21.3.3",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"lokijs": "^1.5.12",
"megalodon": "3.6.7", "megalodon": "3.6.7",
"minimist": "^1.2.5", "minimist": "^1.2.5",
"moment": "^2.29.1", "moment": "^2.29.1",
@ -125,6 +126,7 @@
"@types/i18next": "^13.0.0", "@types/i18next": "^13.0.0",
"@types/jest": "27.0.2", "@types/jest": "27.0.2",
"@types/lodash": "^4.14.176", "@types/lodash": "^4.14.176",
"@types/lokijs": "^1.5.7",
"@types/nedb": "^1.8.12", "@types/nedb": "^1.8.12",
"@types/node": "^16.11.6", "@types/node": "^16.11.6",
"@types/parse-link-header": "^1.0.0", "@types/parse-link-header": "^1.0.0",

22
src/main/database.ts Normal file
View File

@ -0,0 +1,22 @@
import Loki from 'lokijs'
const newDB = (file: string): Promise<Loki> => {
return new Promise(resolve => {
const databaseInitializer = () => {
let markers = db.getCollection('markers')
if (markers === null) {
markers = db.addCollection('markers')
}
resolve(db)
}
const db = new Loki(file, {
autoload: true,
autosave: true,
autosaveInterval: 4000,
autoloadCallback: databaseInitializer
})
})
}
export default newDB

View File

@ -55,6 +55,7 @@ import { EnabledTimelines } from '~/src/types/enabledTimelines'
import { Menu as MenuPreferences } from '~/src/types/preference' import { Menu as MenuPreferences } from '~/src/types/preference'
import { LocalMarker } from '~/src/types/localMarker' import { LocalMarker } from '~/src/types/localMarker'
import Marker from './marker' import Marker from './marker'
import newDB from './database'
/** /**
* Context menu * Context menu
@ -141,12 +142,9 @@ unreadNotification.initialize().catch((err: Error) => log.error(err))
const preferencesDBPath = process.env.NODE_ENV === 'production' ? userData + './db/preferences.json' : 'preferences.json' const preferencesDBPath = process.env.NODE_ENV === 'production' ? userData + './db/preferences.json' : 'preferences.json'
const markerDBPath = process.env.NODE_ENV === 'production' ? userData + '/db/marker.db' : 'marker.db' const lokiDatabasePath = process.env.NODE_ENV === 'production' ? userData + '/db/lokiDatabase.db' : 'lokiDatabase.db'
const markerDB = new Datastore({
filename: markerDBPath, let markerRepo: Marker | null = null
autoload: true
})
const markerRepo = new Marker(markerDB)
/** /**
* Cache path * Cache path
@ -257,6 +255,11 @@ const updateDockMenu = async (accountsChange: Array<MenuItemConstructorOptions>)
} }
async function createWindow() { async function createWindow() {
/**
DB
*/
const lokiDB = await newDB(lokiDatabasePath)
markerRepo = new Marker(lokiDB)
/** /**
* List accounts * List accounts
*/ */
@ -1160,11 +1163,17 @@ ipcMain.handle('update-spellchecker-languages', async (_: IpcMainInvokeEvent, la
// marker // marker
ipcMain.handle('get-home-marker', async (_: IpcMainInvokeEvent, ownerID: string) => { ipcMain.handle('get-home-marker', async (_: IpcMainInvokeEvent, ownerID: string) => {
if (markerRepo === null) {
return null
}
const marker = await markerRepo.get(ownerID, 'home') const marker = await markerRepo.get(ownerID, 'home')
return marker return marker
}) })
ipcMain.handle('get-notifications-marker', async (_: IpcMainInvokeEvent, ownerID: string) => { ipcMain.handle('get-notifications-marker', async (_: IpcMainInvokeEvent, ownerID: string) => {
if (markerRepo === null) {
return null
}
const marker = await markerRepo.get(ownerID, 'notifications') const marker = await markerRepo.get(ownerID, 'notifications')
return marker return marker
}) })
@ -1175,6 +1184,9 @@ ipcMain.on(
if (marker.owner_id === null || marker.owner_id === undefined || marker.owner_id === '') { if (marker.owner_id === null || marker.owner_id === undefined || marker.owner_id === '') {
return null return null
} }
if (markerRepo === null) {
return null
}
const res = await markerRepo.save(marker) const res = await markerRepo.save(marker)
return res return res
} }

View File

@ -1,21 +1,22 @@
import { isEmpty } from 'lodash' import { isEmpty } from 'lodash'
import Datastore from 'nedb' import Loki, { Collection } from 'lokijs'
import { LocalMarker } from '~/src/types/localMarker' import { LocalMarker } from '~/src/types/localMarker'
export default class Marker { export default class Marker {
private db: Datastore private markers: Collection<any>
constructor(db: Datastore) { constructor(db: Loki) {
this.db = db this.markers = db.getCollection('markers')
this.db.persistence.setAutocompactionInterval(60000) // milliseconds
} }
private insert(marker: LocalMarker): Promise<LocalMarker> { private insert(marker: LocalMarker): Promise<LocalMarker> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.db.insert(marker, (err, doc) => { try {
if (err) return reject(err) const doc: LocalMarker = this.markers.insert(marker)
resolve(doc) resolve(doc)
}) } catch (err) {
reject(err)
}
}) })
} }
@ -23,18 +24,20 @@ export default class Marker {
// @ts-ignore // @ts-ignore
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// eslint-disable-line no-unused-vars // eslint-disable-line no-unused-vars
this.db.update( try {
{ this.markers.findAndUpdate(
owner_id: marker.owner_id, {
timeline: marker.timeline owner_id: { $eq: marker.owner_id },
}, timeline: { $eq: marker.timeline }
{ $set: marker }, },
{ multi: false }, (item: LocalMarker) => {
err => { item.last_read_id = marker.last_read_id
if (err) return reject(err) }
return this.get(marker.owner_id, marker.timeline) )
} return this.get(marker.owner_id, marker.timeline)
) } catch (err) {
reject(err)
}
}) })
} }
@ -47,21 +50,28 @@ export default class Marker {
public async get(owner_id: string, timeline: 'home' | 'notifications'): Promise<LocalMarker | null> { public async get(owner_id: string, timeline: 'home' | 'notifications'): Promise<LocalMarker | null> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.db.findOne<LocalMarker>({ owner_id: owner_id, timeline: timeline }, (err, doc) => { try {
if (err) return reject(err) const doc: LocalMarker | null = this.markers.findOne({
owner_id: { $eq: owner_id },
timeline: { $eq: timeline }
})
resolve(doc) resolve(doc)
}) } catch (err) {
reject(err)
}
}) })
} }
public async list(owner_id: string): Promise<Array<LocalMarker>> { public async list(owner_id: string): Promise<Array<LocalMarker>> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.db try {
.find<LocalMarker>({ owner_id: owner_id }) const docs: Array<LocalMarker> = this.markers.find({
.exec((err, docs) => { owner_id: { $eq: owner_id }
if (err) return reject(err)
resolve(docs)
}) })
resolve(docs)
} catch (err) {
reject(err)
}
}) })
} }
} }

View File

@ -1592,6 +1592,11 @@
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.176.tgz#641150fc1cda36fbfa329de603bbb175d7ee20c0" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.176.tgz#641150fc1cda36fbfa329de603bbb175d7ee20c0"
integrity sha512-xZmuPTa3rlZoIbtDUyJKZQimJV3bxCmzMIO2c9Pz9afyDro6kr7R79GwcB6mRhuoPmV2p1Vb66WOJH7F886WKQ== integrity sha512-xZmuPTa3rlZoIbtDUyJKZQimJV3bxCmzMIO2c9Pz9afyDro6kr7R79GwcB6mRhuoPmV2p1Vb66WOJH7F886WKQ==
"@types/lokijs@^1.5.7":
version "1.5.7"
resolved "https://registry.yarnpkg.com/@types/lokijs/-/lokijs-1.5.7.tgz#5eb4b189149681a89acad6dc8adb088f6025feb3"
integrity sha512-WEFQLgO3u2Wa7yFybqkTZYumqF1GcHvUwx8Tv2SUHy2qpnIainMMoLmEUGdjhPNp/v5pyC9e91fSMC3mkxBIDw==
"@types/minimatch@*": "@types/minimatch@*":
version "3.0.3" version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
@ -7920,6 +7925,11 @@ loglevel@^1.6.8:
resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197" resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197"
integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw== integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==
lokijs@^1.5.12:
version "1.5.12"
resolved "https://registry.yarnpkg.com/lokijs/-/lokijs-1.5.12.tgz#cb55b37009bdf09ee7952a6adddd555b893653a0"
integrity sha512-Q5ALD6JiS6xAUWCwX3taQmgwxyveCtIIuL08+ml0nHwT3k0S/GIFJN+Hd38b1qYIMaE5X++iqsqWVksz7SYW+Q==
longest@^1.0.1: longest@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"