fix database system (maybe)
This commit is contained in:
parent
011467782d
commit
12fe84bb2d
11 changed files with 97 additions and 131 deletions
|
@ -5,7 +5,6 @@
|
|||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"discord.js": "^14.7.1",
|
||||
"dokdo": "^0.6.2",
|
||||
"dotenv": "^16.0.3",
|
||||
"mysql2": "^3.1.0"
|
||||
},
|
||||
|
@ -13,6 +12,7 @@
|
|||
"@migan/prettier-config": "^1.0.0",
|
||||
"@types/jest": "^29.4.0",
|
||||
"@types/node": "^18.11.18",
|
||||
"cross-env": "^7.0.3",
|
||||
"jest": "^29.4.0",
|
||||
"prettier": "^2.8.3",
|
||||
"ts-jest": "^29.0.5",
|
||||
|
@ -22,8 +22,8 @@
|
|||
},
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"dev": "ts-node src",
|
||||
"start": "node dist",
|
||||
"dev": "cross-env NODE_ENV=development ts-node src",
|
||||
"start": "cross-env NODE_ENV=production node dist",
|
||||
"test": "jest"
|
||||
},
|
||||
"prettier": "@migan/prettier-config"
|
||||
|
|
|
@ -5,8 +5,7 @@ import {
|
|||
GatewayIntentBits,
|
||||
TextChannel,
|
||||
} from 'discord.js'
|
||||
import { Command, noPerm, ChatBot } from './modules'
|
||||
import Dokdo from 'dokdo'
|
||||
import { Command, noPerm, ChatBot, NODE_ENV } from './modules'
|
||||
import { readdirSync } from 'node:fs'
|
||||
import { join } from 'node:path'
|
||||
import 'dotenv/config'
|
||||
|
@ -27,12 +26,14 @@ export default class MuffinAI extends Client {
|
|||
}
|
||||
|
||||
public override login(): Promise<string> {
|
||||
if (NODE_ENV === 'development') this.on('debug', console.info)
|
||||
this.chatBot.train(this)
|
||||
|
||||
readdirSync(join(__dirname, 'Commands')).forEach(file => {
|
||||
const a = require(join(__dirname, 'Commands', file))
|
||||
const b: Command = new a.default()
|
||||
this.#modules.set(b.name, b)
|
||||
if (NODE_ENV === 'development') console.log(b.name)
|
||||
})
|
||||
|
||||
this.once('ready', () => {
|
||||
|
@ -43,17 +44,15 @@ export default class MuffinAI extends Client {
|
|||
console.log(`먹힐 준비 완료`)
|
||||
}).on('messageCreate', async msg => {
|
||||
if (msg.author.bot) return
|
||||
await new Dokdo(this, {
|
||||
prefix,
|
||||
noPerm,
|
||||
aliases: ['테스트'],
|
||||
owners: ['415135882006495242'],
|
||||
}).run(msg)
|
||||
if (msg.content.startsWith('머핀아 ')) {
|
||||
if (msg.channel instanceof TextChannel) {
|
||||
if (msg.channel.nsfw) return
|
||||
await msg.channel.sendTyping()
|
||||
await msg.channel.send(await this.chatBot.getResponse(msg))
|
||||
this.chatBot //
|
||||
.getResponse(msg)
|
||||
.then(response => {
|
||||
msg.channel.send(response)
|
||||
})
|
||||
}
|
||||
} else if (msg.content.startsWith(prefix)) {
|
||||
if (msg.channel instanceof TextChannel) if (msg.channel.nsfw) return
|
||||
|
@ -61,12 +60,13 @@ export default class MuffinAI extends Client {
|
|||
const args: string[] = msg.content
|
||||
.slice(prefix.length)
|
||||
.trim()
|
||||
.split('/ +/g')
|
||||
|
||||
const command = this.#modules.get(args.toString())
|
||||
.split(/ +/g)
|
||||
if (NODE_ENV === 'development') console.log(args)
|
||||
const command = this.#modules.get(args.shift()!.toLowerCase())
|
||||
if (!command) return
|
||||
if (command.noPerm && msg.author.id !== '415135882006495242')
|
||||
return await noPerm(msg)
|
||||
|
||||
command.execute(msg, args)
|
||||
}
|
||||
})
|
||||
|
@ -75,7 +75,6 @@ export default class MuffinAI extends Client {
|
|||
|
||||
public override destroy() {
|
||||
super.destroy()
|
||||
process.exit()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
20
src/Commands/테스트.ts
Normal file
20
src/Commands/테스트.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
import { Command } from '../modules'
|
||||
import { Message } from 'discord.js'
|
||||
import { inspect } from 'node:util'
|
||||
|
||||
export default class extends Command {
|
||||
public constructor() {
|
||||
super('테스트', true)
|
||||
}
|
||||
public async execute(msg: Message, args: string[]) {
|
||||
if (!args) return msg.channel.send('전달받은 인자가 없습니다.')
|
||||
try {
|
||||
const a = eval(args.join(' '))
|
||||
if (inspect(a) === `'${msg.client.token}'`)
|
||||
return msg.channel.send('[discord_token]')
|
||||
await msg.channel.send(`\`\`\`js\n${inspect(a)}\n\`\`\``)
|
||||
} catch (err) {
|
||||
await msg.channel.send(`\`\`\`js\n${err}\n\`\`\``)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,9 +7,9 @@ export default class extends Command {
|
|||
}
|
||||
public async execute(msg: Message, args: string[]) {
|
||||
const conn = await database.getConnection()
|
||||
const [rows] = await conn.query('SELECT * FROM statement;')
|
||||
const [rows] = await conn.query<ResponseData[]>('SELECT * FROM statement;')
|
||||
const muffin: ResponseData[] = []
|
||||
;(rows as ResponseData[]).forEach(row => {
|
||||
rows.forEach(row => {
|
||||
if (row.persona === 'muffin') muffin.push(row)
|
||||
else return
|
||||
})
|
||||
|
|
|
@ -1,42 +1,41 @@
|
|||
import type { Client, Message } from 'discord.js'
|
||||
import database, { ResponseData } from './Database'
|
||||
import database, { ResponseData } from './database'
|
||||
|
||||
export default class ChatBot {
|
||||
public async getResponse(msg: Message): Promise<string> {
|
||||
const conn = await database.getConnection()
|
||||
const request = msg.content.replace('머핀아 ', '')
|
||||
console.log(`⌨️ㅣ${request}`)
|
||||
const [rows] = await conn.query('SELECT * FROM statement;')
|
||||
let response = (rows as ResponseData[])[
|
||||
Math.floor(Math.random() * (rows as ResponseData[]).length)
|
||||
].text
|
||||
console.log(`req: ${request}`)
|
||||
const [rows] = await conn.query<ResponseData[]>('SELECT * FROM statement;')
|
||||
let response = rows[Math.floor(Math.random() * rows.length)].text
|
||||
if (!response) response = '살ㄹ려주세요'
|
||||
|
||||
console.log(`🍰ㅣ${response}`)
|
||||
console.log(`res: ${response}`)
|
||||
conn.release()
|
||||
return response
|
||||
}
|
||||
|
||||
public async train(client: Client): Promise<ChatBot> {
|
||||
public train(client: Client): ChatBot {
|
||||
client.on('messageCreate', async msg => {
|
||||
const conn = await database.getConnection()
|
||||
if (msg.author.bot) return
|
||||
if (msg.author.id !== '1026185545837191238') return
|
||||
const response = this.getResponse(msg)
|
||||
const result = await conn.query('SELECT * FROM statement;')
|
||||
const rows = result[0] as ResponseData[]
|
||||
await conn.beginTransaction()
|
||||
try {
|
||||
await conn.execute(
|
||||
`INSERT INTO statement(id, text, persona, in_response_to) VALUES(?, ?, ?, ?);`,
|
||||
[++rows[rows.length - 1].id, msg.content, 'muffin', response]
|
||||
const conn = await database.getConnection()
|
||||
if (msg.author.id === '1026185545837191238') {
|
||||
const response = await this.getResponse(msg)
|
||||
const [rows] = await conn.query<ResponseData[]>(
|
||||
'SELECT * FROM statement;'
|
||||
)
|
||||
await conn.commit()
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
await conn.rollback()
|
||||
} finally {
|
||||
conn.release()
|
||||
try {
|
||||
await conn.beginTransaction()
|
||||
await conn.execute(
|
||||
'INSERT INTO statement (id, text, persona, in_response_to) VALUES (?, ?, ?, ?);',
|
||||
[++rows[rows.length - 1].id, msg.content, 'muffin', response]
|
||||
)
|
||||
await conn.commit()
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
await conn.rollback()
|
||||
} finally {
|
||||
conn.release()
|
||||
}
|
||||
}
|
||||
})
|
||||
return this
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { createPool } from 'mysql2/promise'
|
||||
import { PoolOptions, createPool, RowDataPacket } from 'mysql2/promise'
|
||||
import 'dotenv/config'
|
||||
|
||||
export interface ResponseData {
|
||||
export interface ResponseData extends RowDataPacket {
|
||||
id: number
|
||||
text: string
|
||||
search_text: string
|
||||
|
@ -12,10 +12,13 @@ export interface ResponseData {
|
|||
persona: string
|
||||
}
|
||||
|
||||
export default createPool({
|
||||
export const config: PoolOptions = {
|
||||
host: process.env.MYSQL_HOST,
|
||||
user: process.env.MYSQL_USER,
|
||||
password: process.env.MYSQL_PASSWORD,
|
||||
database: process.env.MYSQL_DATABASE,
|
||||
port: (process.env.MYSQL_PORT as unknown as number) || 3306,
|
||||
})
|
||||
enableKeepAlive: true,
|
||||
}
|
||||
|
||||
export default createPool(config)
|
5
src/modules/env.ts
Normal file
5
src/modules/env.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
type NODE_ENV_TYPE = 'production' | 'development' | string
|
||||
|
||||
export const NODE_ENV: NODE_ENV_TYPE = process.env.NODE_ENV
|
||||
? process.env.NODE_ENV
|
||||
: 'production'
|
|
@ -1,5 +1,6 @@
|
|||
import ChatBot from './ChatBot'
|
||||
import Command from './Command'
|
||||
import database, { ResponseData } from './Database'
|
||||
import database, { ResponseData, config } from './database'
|
||||
import noPerm from './noPerm'
|
||||
export { ChatBot, Command, database, noPerm, ResponseData }
|
||||
import { NODE_ENV } from './env'
|
||||
export { ChatBot, Command, database, noPerm, ResponseData, config, NODE_ENV }
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
import Database from '../src/modules/Database'
|
||||
import sqlite3 from 'sqlite3'
|
||||
|
||||
describe('Test Database', () => {
|
||||
const DBPATH = `${__dirname}/../db/db.sqlite3`
|
||||
const db = new sqlite3.Database(DBPATH)
|
||||
const getData = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
db.all('SELECT * FROM statement;', async (err, rows) => {
|
||||
if (err) reject(err)
|
||||
resolve(rows)
|
||||
}).close()
|
||||
})
|
||||
}
|
||||
|
||||
test('Get rows', () => {
|
||||
getData().then(async rows =>
|
||||
expect(await new Database(DBPATH).all()).toEqual(rows)
|
||||
)
|
||||
})
|
||||
|
||||
test('Insert row', () => {
|
||||
const db = new Database(DBPATH)
|
||||
return db.all().then(async data1 => {
|
||||
db.run(
|
||||
'INSERT INTO statement(id, text) VALUES(?, ?)',
|
||||
[++data1[data1.length - 1].id, 'TEST'],
|
||||
err => {
|
||||
if (err) throw err
|
||||
}
|
||||
)
|
||||
const data2 = await db.all()
|
||||
expect(data1[data1.length - 1]).not.toEqual(data2[data2.length - 1])
|
||||
})
|
||||
})
|
||||
|
||||
test('Delete row', () => {
|
||||
const db = new Database(DBPATH)
|
||||
return db.all().then(async data1 => {
|
||||
db.run('DELETE FROM statement WHERE text=?;', ['TEST'], err => {
|
||||
if (err) throw err
|
||||
})
|
||||
const data2 = await db.all()
|
||||
expect(data1[data1.length - 1]).not.toEqual(data2[data2.length - 1])
|
||||
})
|
||||
})
|
||||
})
|
||||
*/
|
13
tests/database.test.ts
Normal file
13
tests/database.test.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
import { database, config } from '../src/modules'
|
||||
import { createConnection } from 'mysql2/promise'
|
||||
|
||||
describe('test database system', () => {
|
||||
test('Validate rows', async () => {
|
||||
return database.getConnection().then(async conn1 => {
|
||||
const [rows1] = await conn1.query('SELECT * FROM statement;')
|
||||
const conn2 = await createConnection(config)
|
||||
const [rows2] = await conn2.query(`SELECT * FROM statement;`)
|
||||
expect(rows1).toEqual(rows2)
|
||||
})
|
||||
})
|
||||
})
|
41
yarn.lock
41
yarn.lock
|
@ -1135,7 +1135,14 @@ create-require@^1.1.0:
|
|||
resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
|
||||
integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
|
||||
|
||||
cross-spawn@^7.0.3:
|
||||
cross-env@^7.0.3:
|
||||
version "7.0.3"
|
||||
resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf"
|
||||
integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==
|
||||
dependencies:
|
||||
cross-spawn "^7.0.1"
|
||||
|
||||
cross-spawn@^7.0.1, cross-spawn@^7.0.3:
|
||||
version "7.0.3"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
|
||||
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
|
||||
|
@ -1211,13 +1218,6 @@ discord.js@^14.7.1:
|
|||
undici "^5.13.0"
|
||||
ws "^8.11.0"
|
||||
|
||||
dokdo@^0.6.2:
|
||||
version "0.6.2"
|
||||
resolved "https://registry.yarnpkg.com/dokdo/-/dokdo-0.6.2.tgz#1e276999f9230f0df54f561992f33a79044d31dc"
|
||||
integrity sha512-o0m3SSFok+OOvX+Oh8hD17Gx4K/AXSeIv7nZtLPmjkUWDzXO4d4mgQK1s82PDy/QOkDEipV9mm5x8gUNoYHRqA==
|
||||
dependencies:
|
||||
node-fetch "^2.6.1"
|
||||
|
||||
dotenv@^16.0.3:
|
||||
version "16.0.3"
|
||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07"
|
||||
|
@ -2311,13 +2311,6 @@ natural-compare@^1.4.0:
|
|||
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
||||
integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
|
||||
|
||||
node-fetch@^2.6.1:
|
||||
version "2.6.8"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.8.tgz#a68d30b162bc1d8fd71a367e81b997e1f4d4937e"
|
||||
integrity sha512-RZ6dBYuj8dRSfxpUSu+NsdF1dpPpluJxwOp+6IoDp/sH2QNDSvurYsAa+F1WxY2RjA1iP93xhcsUoYbF2XBqVg==
|
||||
dependencies:
|
||||
whatwg-url "^5.0.0"
|
||||
|
||||
node-int64@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
|
||||
|
@ -2808,11 +2801,6 @@ tr46@^1.0.1:
|
|||
dependencies:
|
||||
punycode "^2.1.0"
|
||||
|
||||
tr46@~0.0.3:
|
||||
version "0.0.3"
|
||||
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
|
||||
integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
|
||||
|
||||
tree-kill@^1.2.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc"
|
||||
|
@ -2942,24 +2930,11 @@ walker@^1.0.8:
|
|||
dependencies:
|
||||
makeerror "1.0.12"
|
||||
|
||||
webidl-conversions@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
|
||||
integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==
|
||||
|
||||
webidl-conversions@^4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"
|
||||
integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==
|
||||
|
||||
whatwg-url@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
|
||||
integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==
|
||||
dependencies:
|
||||
tr46 "~0.0.3"
|
||||
webidl-conversions "^3.0.0"
|
||||
|
||||
whatwg-url@^7.0.0:
|
||||
version "7.1.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06"
|
||||
|
|
Loading…
Reference in a new issue