feat: separate database

This commit is contained in:
Siwoo Jeon 2023-11-29 20:43:24 +09:00
parent d11050f811
commit e6b73d8507
Signed by: migan
GPG key ID: C4151385FFD2082A
11 changed files with 138 additions and 126 deletions

2
.gitignore vendored
View file

@ -138,4 +138,4 @@ config.json
db/
.idea/
database/
./database/

View file

@ -1,6 +1,6 @@
{
"name": "muffin-ai-arujak",
"version": "2.0.0-72-oreo",
"version": "2.0.0-73-oreo",
"main": "dist/index.js",
"private": true,
"dependencies": {

View file

@ -1,5 +1,5 @@
import type { Client, Message } from 'discord.js'
import database, { LearnData, ResponseData } from './database'
import { database, LearnData, ResponseData } from './database'
import { TextChannel } from 'discord.js'
import config from '../../config.json'
import { NODE_ENV } from '.'

View file

@ -1,122 +0,0 @@
import {
type RowDataPacket,
createPool,
Pool,
PoolConnection,
} from 'mysql2/promise'
import config from '../../config.json'
import { type Snowflake } from 'discord.js'
export interface BaseData extends RowDataPacket {
id: number
text: string
created_at: string
persona: string
}
export interface ResponseData extends BaseData {
search_text: string
conversation: string
in_response_to: string | null
search_in_response_to: string
}
export interface LearnData extends RowDataPacket {
command: string
result: string
user_id: Snowflake
created_at: string
}
export { BaseData as NSFWData }
interface BassTable<T, V> {
name: string
all(): Promise<T[]>
findOne(key: V): Promise<T[]>
insert(data: T): Promise<void>
update(data: T): Promise<void>
delete(key: V): Promise<void>
}
async function run(db: PoolConnection, fn: () => Promise<void>) {
try {
await db.beginTransaction()
await fn()
await db.commit()
} catch (err) {
console.error(err)
await db.rollback()
} finally {
db.release()
}
}
class StatementTable implements BassTable<ResponseData, number> {
public name = 'statement'
public constructor(private _database: Pool) {}
public async all(): Promise<ResponseData[]> {
const [rows] = await this._database.execute<ResponseData[]>(
'SELECT * FROM statement;',
)
return rows
}
public async findOne(key: number): Promise<ResponseData[]> {
const [rows] = await this._database.execute<ResponseData[]>(
'SELECT * FROM statement WHERE id = ?;',
[key],
)
return rows
}
public async insert(data: ResponseData): Promise<void> {
const db = await this._database.getConnection()
await run(db, async () => {
await db.execute(
'INSERT INTO statement (id, text, persona, in_response_to) VALUES (?, ?, ?, ?);',
[data.id, data.text, data.persona, data.in_response_to],
)
})
}
public async update(data: { id: number; text: string }): Promise<void> {
const db = await this._database.getConnection()
await run(db, async () => {
await db.execute('UPDATE statement SET text = ? WHERE id = ?;', [
data.text,
data.id,
])
})
}
public async delete(key: number): Promise<void> {
const db = await this._database.getConnection()
await run(db, async () => {
await db.execute('DELETE FROM statement WHERE id = ?;', [key])
})
}
}
export class MaaDatabase {
private _database = createPool({
...config.mysql,
keepAliveInitialDelay: 10000,
enableKeepAlive: true,
})
public get statement() {
return new StatementTable(this._database)
}
}
const database = createPool({
...config.mysql,
keepAliveInitialDelay: 10000,
enableKeepAlive: true,
})
export default database

View file

@ -0,0 +1,23 @@
import { createPool } from 'mysql2/promise'
import { StatementTable } from './model'
import config from '../../../config.json'
export class MaaDatabase {
private _database = createPool({
...config.mysql,
keepAliveInitialDelay: 10000,
enableKeepAlive: true,
})
public get statement() {
return new StatementTable(this._database)
}
}
const database = createPool({
...config.mysql,
keepAliveInitialDelay: 10000,
enableKeepAlive: true,
})
export { database }

View file

@ -0,0 +1,3 @@
export * from './database'
export * from './type'
export * from './model'

View file

@ -0,0 +1 @@
export * from './statement'

View file

@ -0,0 +1,58 @@
import { type Pool } from 'mysql2/promise'
import run from '../run'
import type { BaseTable, ResponseData } from '../type'
export class StatementTable implements BaseTable<ResponseData, number> {
public name = 'statement'
public constructor(private _database: Pool) {}
public async all(): Promise<ResponseData[]> {
const [rows] = await this._database.execute<ResponseData[]>(
'SELECT * FROM statement;',
)
return rows
}
public async findOne(key: number): Promise<ResponseData[]> {
const [rows] = await this._database.execute<ResponseData[]>(
'SELECT * FROM statement WHERE id = ?;',
[key],
)
return rows
}
public async insert(data: {
id: number
text: string
persona: string
in_response_to: string
}): Promise<void> {
const db = await this._database.getConnection()
await run(db, async () => {
await db.execute(
'INSERT INTO statement (id, text, persona, in_response_to) VALUES (?, ?, ?, ?);',
[data.id, data.text, data.persona, data.in_response_to],
)
})
}
public async update(data: { id: number; text: string }): Promise<void> {
const db = await this._database.getConnection()
await run(db, async () => {
await db.execute('UPDATE statement SET text = ? WHERE id = ?;', [
data.text,
data.id,
])
})
}
public async delete(key: number): Promise<void> {
const db = await this._database.getConnection()
await run(db, async () => {
await db.execute('DELETE FROM statement WHERE id = ?;', [key])
})
}
}

View file

@ -0,0 +1,14 @@
import { type PoolConnection } from 'mysql2/promise'
export default async function run(db: PoolConnection, fn: () => Promise<void>) {
try {
await db.beginTransaction()
await fn()
await db.commit()
} catch (err) {
console.error(err)
await db.rollback()
} finally {
db.release()
}
}

View file

@ -0,0 +1,34 @@
import type { RowDataPacket } from 'mysql2/promise'
import type { Snowflake } from 'discord.js'
export interface BaseData extends RowDataPacket {
id: number
text: string
created_at: string
persona: string
}
export interface ResponseData extends BaseData {
search_text: string
conversation: string
in_response_to: string | null
search_in_response_to: string
}
export interface LearnData extends RowDataPacket {
command: string
result: string
user_id: Snowflake
created_at: string
}
export { BaseData as NSFWData }
export interface BaseTable<T, V> {
name: string
all(): Promise<T[]>
findOne(key: V): Promise<T[]>
insert(data: any): Promise<void>
update(data: any): Promise<void>
delete(key: V): Promise<void>
}

View file

@ -1,6 +1,7 @@
import ChatBot from './ChatBot'
import Command from './Command'
import database, {
import {
database,
ResponseData,
NSFWData,
LearnData,