mirror of
https://github.com/h3poteto/whalebird-desktop
synced 2025-02-06 20:33:33 +01:00
refs #2500 Change hashtags database to sqlite3
This commit is contained in:
parent
5098c4ee67
commit
654f4af1ec
@ -36,6 +36,18 @@ FOREIGN KEY (account_id) REFERENCES accounts(id) ON DELETE CASCADE)',
|
||||
}
|
||||
}
|
||||
)
|
||||
db.run(
|
||||
'CREATE TABLE IF NOT EXISTS hashtags(\
|
||||
id INTEGER PRIMARY KEY, \
|
||||
tag TEXT NOT NULL, \
|
||||
account_id INTEGER UNIQUE NOT NULL, \
|
||||
FOREIGN KEY (account_id) REFERENCES accounts(id) ON DELETE CASCADE)',
|
||||
err => {
|
||||
if (err) {
|
||||
console.error('failed to create hashtags: ', err)
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
return db
|
||||
|
@ -1,44 +1,63 @@
|
||||
import Datastore from 'nedb'
|
||||
import sqlite3 from 'sqlite3'
|
||||
import { LocalTag } from '~/src/types/localTag'
|
||||
|
||||
export default class Hashtags {
|
||||
private db: Datastore
|
||||
|
||||
constructor(db: Datastore) {
|
||||
this.db = db
|
||||
this.db.ensureIndex({ fieldName: 'tagName', unique: true }, _ => {})
|
||||
}
|
||||
|
||||
listTags(): Promise<Array<LocalTag>> {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.db.find<LocalTag>({}, (err, docs) => {
|
||||
if (err) return reject(err)
|
||||
resolve(docs)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
insertTag(tag: string): Promise<LocalTag> {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.db.insert({ tagName: tag }, (err, doc) => {
|
||||
if (err) return reject(err)
|
||||
resolve(doc)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
removeTag(localTag: LocalTag): Promise<number> {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.db.remove(
|
||||
{
|
||||
tagName: localTag.tagName
|
||||
},
|
||||
{ multi: true },
|
||||
(err, numRemoved) => {
|
||||
if (err) return reject(err)
|
||||
resolve(numRemoved)
|
||||
}
|
||||
export const listTags = (db: sqlite3.Database, accountId: number): Promise<Array<LocalTag>> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
db.all('SELECT * FROM hashtags WHERE account_id = ?', accountId, (err, rows) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
}
|
||||
resolve(
|
||||
rows.map(r => ({
|
||||
id: r.id,
|
||||
tagName: r.tag,
|
||||
accountId: r.account_id
|
||||
}))
|
||||
)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const insertTag = (db: sqlite3.Database, accountId: number, tag: string): Promise<LocalTag> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
db.serialize(() => {
|
||||
db.run('BEGIN TRANSACTION')
|
||||
|
||||
db.get('SELECT * FROM hashtags WHERE id = ? AND tag = ?', [accountId, tag], (err, row) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
}
|
||||
if (row) {
|
||||
resolve({
|
||||
id: row.id,
|
||||
tagName: row.tag,
|
||||
accountId: row.account_id
|
||||
})
|
||||
}
|
||||
|
||||
db.run('INSERT INTO hashtags(tag, account_id) VALUES (?, ?)', [accountId, tag], function (err) {
|
||||
if (err) {
|
||||
reject(err)
|
||||
}
|
||||
db.run('COMMIT')
|
||||
resolve({
|
||||
id: this.lastID,
|
||||
tagName: tag,
|
||||
accountId: accountId
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export const removeTag = (db: sqlite3.Database, tag: LocalTag): Promise<null> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
db.run('DELETE FROM hashtags WHERE id = ?', tag.id, err => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
}
|
||||
resolve(null)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -35,7 +35,6 @@ import { getAccount, insertAccount, listAccounts } from './account'
|
||||
// import { StreamingURL, UserStreaming, DirectStreaming, LocalStreaming, PublicStreaming, ListStreaming, TagStreaming } from './websocket'
|
||||
import Preferences from './preferences'
|
||||
import Fonts from './fonts'
|
||||
import Hashtags from './hashtags'
|
||||
import i18next from '~/src/config/i18n'
|
||||
import { i18n as I18n } from 'i18next'
|
||||
import Language, { LanguageType } from '../constants/language'
|
||||
@ -55,6 +54,7 @@ import Settings from './settings'
|
||||
import { BaseSettings, Setting } from '~/src/types/setting'
|
||||
import { insertServer } from './server'
|
||||
import { LocalServer } from '~src/types/localServer'
|
||||
import { insertTag, listTags, removeTag } from './hashtags'
|
||||
|
||||
/**
|
||||
* Context menu
|
||||
@ -126,12 +126,6 @@ const db = newDB(databasePath)
|
||||
|
||||
const preferencesDBPath = process.env.NODE_ENV === 'production' ? userData + './db/preferences.json' : 'preferences.json'
|
||||
|
||||
const hashtagsDBPath = process.env.NODE_ENV === 'production' ? userData + '/db/hashtags.db' : 'hashtags.db'
|
||||
const hashtagsDB = new Datastore({
|
||||
filename: hashtagsDBPath,
|
||||
autoload: true
|
||||
})
|
||||
|
||||
const settingsDBPath = process.env.NODE_ENV === 'production' ? userData + './db/settings.json' : 'settings.json'
|
||||
|
||||
/**
|
||||
@ -1136,20 +1130,17 @@ ipcMain.handle('update-spellchecker-languages', async (_: IpcMainInvokeEvent, la
|
||||
})
|
||||
|
||||
// hashtag
|
||||
ipcMain.handle('save-hashtag', async (_: IpcMainInvokeEvent, tag: string) => {
|
||||
const hashtags = new Hashtags(hashtagsDB)
|
||||
await hashtags.insertTag(tag)
|
||||
ipcMain.handle('save-hashtag', async (_: IpcMainInvokeEvent, req: { accountId: number; tag: string }) => {
|
||||
await insertTag(db, req.accountId, req.tag)
|
||||
})
|
||||
|
||||
ipcMain.handle('list-hashtags', async (_: IpcMainInvokeEvent) => {
|
||||
const hashtags = new Hashtags(hashtagsDB)
|
||||
const tags = await hashtags.listTags()
|
||||
ipcMain.handle('list-hashtags', async (_: IpcMainInvokeEvent, accountId: number) => {
|
||||
const tags = await listTags(db, accountId)
|
||||
return tags
|
||||
})
|
||||
|
||||
ipcMain.handle('remove-hashtag', async (_: IpcMainInvokeEvent, tag: LocalTag) => {
|
||||
const hashtags = new Hashtags(hashtagsDB)
|
||||
await hashtags.removeTag(tag)
|
||||
await removeTag(db, tag)
|
||||
})
|
||||
|
||||
// Fonts
|
||||
|
@ -18,8 +18,8 @@ export type HashtagModuleState = HashtagModule & HashtagState
|
||||
const state = (): HashtagState => ({})
|
||||
|
||||
const actions: ActionTree<HashtagState, RootState> = {
|
||||
saveTag: async ({ dispatch }, tag: string) => {
|
||||
await win.ipcRenderer.invoke('save-hashtag', tag)
|
||||
saveTag: async ({ dispatch, rootState }, tag: string) => {
|
||||
await win.ipcRenderer.invoke('save-hashtag', { accountId: rootState.TimelineSpace.account!.id, tag })
|
||||
dispatch('TimelineSpace/SideMenu/listTags', {}, { root: true })
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import { RootState } from '@/store'
|
||||
import { MyWindow } from '~/src/types/global'
|
||||
import { toRaw } from 'vue'
|
||||
|
||||
const win = window as any as MyWindow
|
||||
const win = (window as any) as MyWindow
|
||||
|
||||
export type ListState = {
|
||||
tags: Array<LocalTag>
|
||||
@ -30,14 +30,14 @@ export const ACTION_TYPES = {
|
||||
}
|
||||
|
||||
const actions: ActionTree<ListState, RootState> = {
|
||||
[ACTION_TYPES.LIST_TAGS]: async ({ commit }) => {
|
||||
const tags: Array<LocalTag> = await win.ipcRenderer.invoke('list-hashtags')
|
||||
[ACTION_TYPES.LIST_TAGS]: async ({ rootState, commit }) => {
|
||||
const tags: Array<LocalTag> = await win.ipcRenderer.invoke('list-hashtags', rootState.TimelineSpace.account!.id)
|
||||
commit(MUTATION_TYPES.UPDATE_TAGS, tags)
|
||||
return tags
|
||||
},
|
||||
[ACTION_TYPES.REMOVE_TAG]: async ({ dispatch }, tag: LocalTag) => {
|
||||
await win.ipcRenderer.invoke('remove-hashtag', toRaw(tag))
|
||||
dispatch('listTags')
|
||||
dispatch(ACTION_TYPES.LIST_TAGS)
|
||||
dispatch('TimelineSpace/SideMenu/listTags', {}, { root: true })
|
||||
return 'deleted'
|
||||
}
|
||||
|
@ -223,8 +223,10 @@ const actions: ActionTree<SideMenuState, RootState> = {
|
||||
commit(MUTATION_TYPES.CHANGE_COLLAPSE, value)
|
||||
return value
|
||||
},
|
||||
[ACTION_TYPES.LIST_TAGS]: async ({ commit }) => {
|
||||
const tags: Array<LocalTag> = await win.ipcRenderer.invoke('list-hashtags')
|
||||
[ACTION_TYPES.LIST_TAGS]: async ({ rootState, commit }) => {
|
||||
// TODO: Can not get account because too early.
|
||||
// It should be executed after TimelineSpace obtain local account.
|
||||
const tags: Array<LocalTag> = await win.ipcRenderer.invoke('list-hashtags', rootState.TimelineSpace.account!.id)
|
||||
commit(MUTATION_TYPES.UPDATE_TAGS, tags)
|
||||
return tags
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
export type LocalTag = {
|
||||
id: number
|
||||
tagName: string
|
||||
_id?: string
|
||||
accountId: number
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user