2022-09-10 22:51:00 +00:00
import { prefixCache , disabledCmdCache , disabledCache , commands , messageCommands } from "../collections.js" ;
2022-02-19 05:05:41 +00:00
import * as logger from "../logger.js" ;
2020-12-19 00:50:25 +00:00
2021-08-19 14:19:14 +00:00
import Postgres from "pg" ;
const connection = new Postgres . Pool ( {
2021-08-10 23:35:26 +00:00
connectionString : process . env . DB ,
statement _timeout : 10000
2020-12-19 00:50:25 +00:00
} ) ;
2022-02-19 05:05:41 +00:00
const psqlUpdates = [
"" , // reserved
2022-03-01 15:49:36 +00:00
"CREATE TABLE IF NOT EXISTS settings ( id smallint PRIMARY KEY, version integer NOT NULL, CHECK(id = 1) );\nALTER TABLE guilds ADD COLUMN accessed timestamp;" ,
2022-02-22 00:55:25 +00:00
"ALTER TABLE guilds DROP COLUMN accessed"
2022-02-19 05:05:41 +00:00
] ;
2022-02-22 00:55:25 +00:00
export async function setup ( ) {
2022-02-19 05:05:41 +00:00
let counts ;
try {
counts = await connection . query ( "SELECT * FROM counts" ) ;
} catch {
counts = { rows : [ ] } ;
}
2022-09-10 22:51:00 +00:00
const merged = new Map ( [ ... commands , ... messageCommands ] ) ;
2022-02-19 05:05:41 +00:00
if ( ! counts . rows [ 0 ] ) {
2022-09-10 22:51:00 +00:00
for ( const command of merged . keys ( ) ) {
2022-02-19 05:05:41 +00:00
await connection . query ( "INSERT INTO counts (command, count) VALUES ($1, $2)" , [ command , 0 ] ) ;
}
} else {
const exists = [ ] ;
2022-09-10 22:51:00 +00:00
for ( const command of merged . keys ( ) ) {
2022-02-19 05:05:41 +00:00
const count = await connection . query ( "SELECT * FROM counts WHERE command = $1" , [ command ] ) ;
if ( ! count . rows [ 0 ] ) {
await connection . query ( "INSERT INTO counts (command, count) VALUES ($1, $2)" , [ command , 0 ] ) ;
}
exists . push ( command ) ;
}
for ( const { command } of counts . rows ) {
if ( ! exists . includes ( command ) ) {
await connection . query ( "DELETE FROM counts WHERE command = $1" , [ command ] ) ;
}
}
}
}
2022-02-22 00:55:25 +00:00
export async function upgrade ( logger ) {
let version ;
try {
version = ( await connection . query ( "SELECT version FROM settings WHERE id = 1" ) ) . rows [ 0 ] . version ;
} catch {
version = 0 ;
}
if ( version < ( psqlUpdates . length - 1 ) ) {
logger . warn ( ` Migrating PostgreSQL database, which is currently at version ${ version } ... ` ) ;
await connection . query ( "BEGIN" ) ;
try {
while ( version < ( psqlUpdates . length - 1 ) ) {
version ++ ;
logger . warn ( ` Running version ${ version } update script ( ${ psqlUpdates [ version ] } )... ` ) ;
await connection . query ( psqlUpdates [ version ] ) ;
}
await connection . query ( "COMMIT" ) ;
await connection . query ( "INSERT INTO settings (id, version) VALUES (1, $1) ON CONFLICT (id) DO UPDATE SET version = $1" , [ psqlUpdates . length - 1 ] ) ;
} catch ( e ) {
logger . error ( ` PostgreSQL migration failed: ${ e } ` ) ;
await connection . query ( "ROLLBACK" ) ;
logger . error ( "Unable to start the bot, quitting now." ) ;
return 1 ;
}
}
2021-08-19 14:19:14 +00:00
}
2020-12-19 00:50:25 +00:00
2022-02-22 00:55:25 +00:00
export async function getGuild ( query ) {
return ( await connection . query ( "SELECT * FROM guilds WHERE guild_id = $1" , [ query ] ) ) . rows [ 0 ] ;
2022-02-19 05:05:41 +00:00
}
2021-08-19 14:19:14 +00:00
export async function setPrefix ( prefix , guild ) {
2020-12-19 00:50:25 +00:00
await connection . query ( "UPDATE guilds SET prefix = $1 WHERE guild_id = $2" , [ prefix , guild . id ] ) ;
2021-08-19 14:19:14 +00:00
prefixCache . set ( guild . id , prefix ) ;
}
2020-12-19 00:50:25 +00:00
2021-08-19 14:19:14 +00:00
export async function getTag ( guild , tag ) {
2021-08-14 13:00:16 +00:00
const tagResult = ( await connection . query ( "SELECT * FROM tags WHERE guild_id = $1 AND name = $2" , [ guild , tag ] ) ) . rows ;
return tagResult [ 0 ] ? { content : tagResult [ 0 ] . content , author : tagResult [ 0 ] . author } : undefined ;
2021-08-19 14:19:14 +00:00
}
2021-08-14 13:00:16 +00:00
2021-08-19 14:19:14 +00:00
export async function getTags ( guild ) {
2021-08-11 01:25:29 +00:00
const tagArray = ( await connection . query ( "SELECT * FROM tags WHERE guild_id = $1" , [ guild ] ) ) . rows ;
const tags = { } ;
for ( const tag of tagArray ) {
tags [ tag . name ] = { content : tag . content , author : tag . author } ;
}
return tags ;
2021-08-19 14:19:14 +00:00
}
2021-08-11 01:25:29 +00:00
2021-08-19 14:19:14 +00:00
export async function setTag ( name , content , guild ) {
2021-08-11 01:25:29 +00:00
await connection . query ( "INSERT INTO tags (guild_id, name, content, author) VALUES ($1, $2, $3, $4)" , [ guild . id , name , content . content , content . author ] ) ;
2021-08-19 14:19:14 +00:00
}
2021-08-11 01:25:29 +00:00
2021-08-19 14:19:14 +00:00
export async function editTag ( name , content , guild ) {
2021-08-11 01:25:29 +00:00
await connection . query ( "UPDATE tags SET content = $1, author = $2 WHERE guild_id = $3 AND name = $4" , [ content . content , content . author , guild . id , name ] ) ;
2021-08-19 14:19:14 +00:00
}
2020-12-19 00:50:25 +00:00
2021-08-19 14:19:14 +00:00
export async function removeTag ( name , guild ) {
2021-08-11 01:25:29 +00:00
await connection . query ( "DELETE FROM tags WHERE guild_id = $1 AND name = $2" , [ guild . id , name ] ) ;
2021-08-19 14:19:14 +00:00
}
2020-12-19 00:50:25 +00:00
2021-08-19 14:19:14 +00:00
export async function disableCommand ( guild , command ) {
2021-08-13 03:28:09 +00:00
const guildDB = await this . getGuild ( guild ) ;
2022-01-07 17:44:18 +00:00
await connection . query ( "UPDATE guilds SET disabled_commands = $1 WHERE guild_id = $2" , [ ( guildDB . disabled _commands ? [ ... guildDB . disabled _commands , command ] : [ command ] ) . filter ( ( v ) => ! ! v ) , guild ] ) ;
disabledCmdCache . set ( guild , guildDB . disabled _commands ? [ ... guildDB . disabled _commands , command ] : [ command ] . filter ( ( v ) => ! ! v ) ) ;
2021-08-19 14:19:14 +00:00
}
2021-08-13 03:28:09 +00:00
2021-08-19 14:19:14 +00:00
export async function enableCommand ( guild , command ) {
2021-08-13 03:28:09 +00:00
const guildDB = await this . getGuild ( guild ) ;
const newDisabled = guildDB . disabled _commands ? guildDB . disabled _commands . filter ( item => item !== command ) : [ ] ;
await connection . query ( "UPDATE guilds SET disabled_commands = $1 WHERE guild_id = $2" , [ newDisabled , guild ] ) ;
2021-08-19 14:19:14 +00:00
disabledCmdCache . set ( guild , newDisabled ) ;
}
2020-12-19 00:50:25 +00:00
2021-08-19 14:19:14 +00:00
export async function disableChannel ( channel ) {
2020-12-19 00:50:25 +00:00
const guildDB = await this . getGuild ( channel . guild . id ) ;
await connection . query ( "UPDATE guilds SET disabled = $1 WHERE guild_id = $2" , [ [ ... guildDB . disabled , channel . id ] , channel . guild . id ] ) ;
2021-08-19 14:19:14 +00:00
disabledCache . set ( channel . guild . id , [ ... guildDB . disabled , channel . id ] ) ;
}
2020-12-19 00:50:25 +00:00
2021-08-19 14:19:14 +00:00
export async function enableChannel ( channel ) {
2020-12-19 00:50:25 +00:00
const guildDB = await this . getGuild ( channel . guild . id ) ;
const newDisabled = guildDB . disabled . filter ( item => item !== channel . id ) ;
await connection . query ( "UPDATE guilds SET disabled = $1 WHERE guild_id = $2" , [ newDisabled , channel . guild . id ] ) ;
2021-08-19 14:19:14 +00:00
disabledCache . set ( channel . guild . id , newDisabled ) ;
}
2020-12-19 00:50:25 +00:00
2021-08-19 14:19:14 +00:00
export async function getCounts ( ) {
2020-12-19 00:50:25 +00:00
const counts = await connection . query ( "SELECT * FROM counts" ) ;
2021-05-03 13:49:55 +00:00
//const countArray = [];
const countObject = { } ;
2020-12-19 00:50:25 +00:00
for ( const { command , count } of counts . rows ) {
2021-05-03 13:49:55 +00:00
countObject [ command ] = count ;
2020-12-19 00:50:25 +00:00
}
2021-05-03 13:49:55 +00:00
return countObject ;
2021-08-19 14:19:14 +00:00
}
2020-12-19 00:50:25 +00:00
2021-08-19 14:19:14 +00:00
export async function addCount ( command ) {
2021-08-11 21:54:43 +00:00
let count = await connection . query ( "SELECT * FROM counts WHERE command = $1" , [ command ] ) ;
2021-04-01 03:16:23 +00:00
if ( ! count . rows [ 0 ] ) {
await connection . query ( "INSERT INTO counts (command, count) VALUES ($1, $2)" , [ command , 0 ] ) ;
2021-08-11 21:54:43 +00:00
count = await connection . query ( "SELECT * FROM counts WHERE command = $1" , [ command ] ) ;
2021-04-01 03:16:23 +00:00
}
2021-01-08 18:08:10 +00:00
await connection . query ( "UPDATE counts SET count = $1 WHERE command = $2" , [ count . rows [ 0 ] . count ? count . rows [ 0 ] . count + 1 : 1 , command ] ) ;
2021-08-19 14:19:14 +00:00
}
2020-12-19 00:50:25 +00:00
2021-08-19 14:19:14 +00:00
export async function addGuild ( guild ) {
Class commands, improved sharding, and many other changes (#88)
* Load commands recursively
* Sort commands
* Missed a couple of spots
* missed even more spots apparently
* Ported commands in "fun" category to new class-based format, added babel eslint plugin
* Ported general commands, removed old/unneeded stuff, replaced moment with day, many more fixes I lost track of
* Missed a spot
* Removed unnecessary abort-controller package, add deprecation warning for mongo database
* Added imagereload, clarified premature end message
* Fixed docker-compose path issue, added total bot uptime to stats, more fixes for various parts
* Converted image commands into classes, fixed reload, ignore another WS event, cleaned up command handler and image runner
* Converted music/soundboard commands to class format
* Cleanup unnecessary logs
* awful tag command class port
* I literally somehow just learned that you can leave out the constructor in classes
* Pass client directly to commands/events, cleaned up command handler
* Migrated bot to eris-sharder, fixed some error handling stuff
* Remove unused modules
* Fixed type returning
* Switched back to Eris stable
* Some fixes and cleanup
* might wanna correct this
* Implement image command ratelimiting
* Added Bot token prefix, added imagestats, added running endpoint to API
2021-04-12 16:16:12 +00:00
const query = await this . getGuild ( guild ) ;
if ( query ) return query ;
2021-08-14 13:00:16 +00:00
try {
await connection . query ( "INSERT INTO guilds (guild_id, prefix, disabled, disabled_commands) VALUES ($1, $2, $3, $4)" , [ guild . id , process . env . PREFIX , [ ] , [ ] ] ) ;
} catch ( e ) {
2022-02-19 05:05:41 +00:00
logger . error ( ` Failed to register guild ${ guild . id } : ${ e } ` ) ;
2021-08-14 13:00:16 +00:00
}
2020-12-19 00:50:25 +00:00
return await this . getGuild ( guild . id ) ;
2021-08-19 14:19:14 +00:00
}
2020-12-19 00:50:25 +00:00
2021-08-19 14:19:14 +00:00
export async function fixGuild ( guild ) {
2021-08-09 15:12:48 +00:00
const guildDB = await connection . query ( "SELECT exists(SELECT 1 FROM guilds WHERE guild_id = $1)" , [ guild . id ] ) ;
2021-08-09 15:48:43 +00:00
if ( ! guildDB . rows [ 0 ] . exists ) {
2022-02-19 05:05:41 +00:00
logger . log ( ` Registering guild database entry for guild ${ guild . id } ... ` ) ;
2020-12-19 00:50:25 +00:00
return await this . addGuild ( guild ) ;
}
2021-08-19 14:19:14 +00:00
}
2020-12-19 00:50:25 +00:00
2021-08-19 14:19:14 +00:00
export async function stop ( ) {
2020-12-19 00:57:41 +00:00
await connection . end ( ) ;
2022-01-07 17:44:18 +00:00
}