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
2022-09-12 21:45:32 +00:00
import Postgres from "postgres" ;
const sql = Postgres ( process . env . DB ) ;
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-10-25 17:37:55 +00:00
"ALTER TABLE guilds DROP COLUMN accessed" ,
2022-10-30 05:17:36 +00:00
"ALTER TABLE settings ADD COLUMN IF NOT EXISTS broadcast text"
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 {
2022-09-12 21:45:32 +00:00
counts = await sql ` SELECT * FROM counts ` ;
2022-02-19 05:05:41 +00:00
} catch {
2022-09-12 21:45:32 +00:00
counts = [ ] ;
2022-02-19 05:05:41 +00:00
}
2022-09-10 22:51:00 +00:00
const merged = new Map ( [ ... commands , ... messageCommands ] ) ;
2022-09-12 21:45:32 +00:00
if ( ! counts . length ) {
2022-09-10 22:51:00 +00:00
for ( const command of merged . keys ( ) ) {
2022-09-12 21:45:32 +00:00
await sql ` INSERT INTO counts ${ sql ( { command , count : 0 } , "command", "count")} ` ;
2022-02-19 05:05:41 +00:00
}
} else {
const exists = [ ] ;
2022-09-10 22:51:00 +00:00
for ( const command of merged . keys ( ) ) {
2022-09-12 21:45:32 +00:00
const count = await sql ` SELECT * FROM counts WHERE command = ${ command } ` ;
if ( ! count . length ) {
await sql ` INSERT INTO counts ${ sql ( { command , count : 0 } , "command", "count")} ` ;
2022-02-19 05:05:41 +00:00
}
exists . push ( command ) ;
}
2022-09-12 21:45:32 +00:00
for ( const { command } of counts ) {
2022-02-19 05:05:41 +00:00
if ( ! exists . includes ( command ) ) {
2022-09-12 21:45:32 +00:00
await sql ` DELETE FROM counts WHERE command = ${ command } ` ;
2022-02-19 05:05:41 +00:00
}
}
}
}
2022-02-22 00:55:25 +00:00
export async function upgrade ( logger ) {
let version ;
try {
2022-09-12 21:45:32 +00:00
version = ( await sql ` SELECT version FROM settings WHERE id = 1 ` ) [ 0 ] . version ;
2022-02-22 00:55:25 +00:00
} catch {
version = 0 ;
}
if ( version < ( psqlUpdates . length - 1 ) ) {
logger . warn ( ` Migrating PostgreSQL database, which is currently at version ${ version } ... ` ) ;
try {
2022-09-12 21:45:32 +00:00
await sql . begin ( async ( db ) => {
while ( version < ( psqlUpdates . length - 1 ) ) {
version ++ ;
logger . warn ( ` Running version ${ version } update script ( ${ psqlUpdates [ version ] } )... ` ) ;
2022-10-25 17:37:55 +00:00
await db . unsafe ( psqlUpdates [ version ] ) ;
2022-09-12 21:45:32 +00:00
}
} ) ;
const ver = psqlUpdates . length - 1 ;
await sql ` INSERT INTO settings ${ sql ( { id : 1 , version : ver } )} ON CONFLICT (id) DO UPDATE SET version = ${ ver } ` ;
2022-02-22 00:55:25 +00:00
} catch ( e ) {
logger . error ( ` PostgreSQL migration failed: ${ e } ` ) ;
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 ) {
2022-09-12 21:45:32 +00:00
return ( await sql ` SELECT * FROM guilds WHERE guild_id = ${ query } ` ) [ 0 ] ;
2022-02-19 05:05:41 +00:00
}
2021-08-19 14:19:14 +00:00
export async function setPrefix ( prefix , guild ) {
2022-09-12 21:45:32 +00:00
await sql ` UPDATE guilds SET prefix = ${ prefix } WHERE guild_id = ${ 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 ) {
2022-09-12 21:45:32 +00:00
const tagResult = await sql ` SELECT * FROM tags WHERE guild_id = ${ guild } AND name = ${ tag } ` ;
2021-08-14 13:00:16 +00:00
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 ) {
2022-09-12 21:45:32 +00:00
const tagArray = await sql ` SELECT * FROM tags WHERE guild_id = ${ guild } ` ;
2021-08-11 01:25:29 +00:00
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 ) {
2022-09-12 21:45:32 +00:00
await sql ` INSERT INTO tags ${ sql ( { guild _id : guild . id , name , content : content . content , author : content . author } , "guild_id", "name", "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 ) {
2022-09-12 21:45:32 +00:00
await sql ` UPDATE tags SET content = ${ content . content } , author = ${ content . author } WHERE guild_id = ${ guild . id } AND name = ${ 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 ) {
2022-09-12 21:45:32 +00:00
await sql ` DELETE FROM tags WHERE guild_id = ${ guild . id } AND name = ${ name } ` ;
2021-08-19 14:19:14 +00:00
}
2020-12-19 00:50:25 +00:00
2022-10-25 17:37:55 +00:00
export async function setBroadcast ( msg ) {
await sql ` UPDATE settings SET broadcast = ${ msg } WHERE id = 1 ` ;
}
export async function getBroadcast ( ) {
const result = await sql ` SELECT broadcast FROM settings WHERE id = 1 ` ;
return result [ 0 ] . broadcast ;
}
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-09-12 21:45:32 +00:00
await sql ` UPDATE guilds SET disabled_commands = ${ ( guildDB . disabled _commands ? [ ... guildDB . disabled _commands , command ] : [ command ] ) . filter ( ( v ) => ! ! v ) } WHERE guild_id = ${ guild } ` ;
2022-01-07 17:44:18 +00:00
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 ) : [ ] ;
2022-09-12 21:45:32 +00:00
await sql ` UPDATE guilds SET disabled_commands = ${ newDisabled } WHERE guild_id = ${ 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 ) {
2022-09-24 03:25:16 +00:00
const guildDB = await this . getGuild ( channel . guildID ) ;
await sql ` UPDATE guilds SET disabled_commands = ${ [ ... guildDB . disabled , channel . id ] } WHERE guild_id = ${ channel . guildID } ` ;
disabledCache . set ( channel . guildID , [ ... guildDB . disabled , channel . 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 enableChannel ( channel ) {
2022-09-24 03:25:16 +00:00
const guildDB = await this . getGuild ( channel . guildID ) ;
2020-12-19 00:50:25 +00:00
const newDisabled = guildDB . disabled . filter ( item => item !== channel . id ) ;
2022-09-24 03:25:16 +00:00
await sql ` UPDATE guilds SET disabled_commands = ${ newDisabled } WHERE guild_id = ${ channel . guildID } ` ;
disabledCache . set ( channel . guildID , newDisabled ) ;
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 getCounts ( ) {
2022-09-12 21:45:32 +00:00
const counts = await sql ` SELECT * FROM counts ` ;
2021-05-03 13:49:55 +00:00
const countObject = { } ;
2022-09-12 21:45:32 +00:00
for ( const { command , count } of counts ) {
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 ) {
2022-09-12 21:45:32 +00:00
await sql ` INSERT INTO counts ${ sql ( { command , count : 1 } , "command", "count")} ON CONFLICT (command) DO UPDATE SET count = counts.count + 1 WHERE counts.command = ${ 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 {
2022-10-24 01:27:32 +00:00
await sql ` INSERT INTO guilds ${ sql ( { guild _id : guild , prefix : process . env . PREFIX , disabled : [ ] , disabled _commands : [ ] } )} ` ;
2021-08-14 13:00:16 +00:00
} catch ( e ) {
2022-10-24 01:27:32 +00:00
logger . error ( ` Failed to register guild ${ guild } : ${ e } ` ) ;
2021-08-14 13:00:16 +00:00
}
2022-10-24 01:27:32 +00:00
return await this . getGuild ( 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 fixGuild ( guild ) {
2022-09-29 04:11:05 +00:00
const guildDB = await sql ` SELECT exists(SELECT 1 FROM guilds WHERE guild_id = ${ guild } ) ` ;
2022-09-12 21:45:32 +00:00
if ( ! guildDB [ 0 ] . exists ) {
2022-09-29 04:11:05 +00:00
logger . log ( ` Registering guild database entry for guild ${ guild } ... ` ) ;
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 ( ) {
2022-09-12 21:45:32 +00:00
await sql . end ( ) ;
2022-01-07 17:44:18 +00:00
}