2022-09-10 22:51:00 +00:00
import { prefixCache , disabledCmdCache , disabledCache , commands , messageCommands } from "../collections.js" ;
2020-12-19 00:50:25 +00:00
2022-09-12 21:45:32 +00:00
import Postgres from "postgres" ;
2022-11-26 21:31:00 +00:00
const sql = Postgres ( process . env . DB , {
onnotice : ( ) => { }
} ) ;
2020-12-19 00:50:25 +00:00
2022-11-26 21:31:00 +00:00
const settingsSchema = `
CREATE TABLE IF NOT EXISTS settings (
id smallint PRIMARY KEY ,
version integer NOT NULL , CHECK ( id = 1 )
) ;
` ;
const schema = `
ALTER TABLE settings ADD COLUMN broadcast text ;
CREATE TABLE guilds (
guild _id VARCHAR ( 30 ) NOT NULL PRIMARY KEY ,
prefix VARCHAR ( 15 ) NOT NULL ,
disabled text ARRAY NOT NULL ,
disabled _commands text ARRAY NOT NULL
) ;
CREATE TABLE counts (
command VARCHAR NOT NULL PRIMARY KEY ,
count integer NOT NULL
) ;
CREATE TABLE tags (
guild _id VARCHAR ( 30 ) NOT NULL ,
name text NOT NULL ,
content text NOT NULL ,
author VARCHAR ( 30 ) NOT NULL ,
UNIQUE ( guild _id , name )
) ;
` ;
const updates = [
2022-02-19 05:05:41 +00:00
"" , // 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-12-12 17:15:10 +00:00
const existingCommands = ( await sql ` SELECT command FROM counts ` ) . map ( x => x . command ) ;
const commandNames = [ ... commands . keys ( ) , ... messageCommands . keys ( ) ] ;
for ( const command of existingCommands ) {
if ( ! commandNames . includes ( command ) ) {
await sql ` DELETE FROM counts WHERE command = ${ command } ` ;
2022-02-19 05:05:41 +00:00
}
2022-12-12 17:36:08 +00:00
}
2022-12-12 17:15:10 +00:00
for ( const command of commandNames ) {
if ( ! existingCommands . includes ( command ) ) {
await sql ` INSERT INTO counts ${ sql ( { command , count : 0 } , "command", "count")} ` ;
2022-02-19 05:05:41 +00:00
}
2022-12-12 17:36:08 +00:00
}
2022-02-19 05:05:41 +00:00
}
2022-02-22 00:55:25 +00:00
export async function upgrade ( logger ) {
try {
2022-12-12 17:15:10 +00:00
await sql . begin ( async ( sql ) => {
await sql . unsafe ( settingsSchema ) ;
2022-11-26 21:31:00 +00:00
let version ;
2022-12-12 17:15:10 +00:00
const settingsrow = ( await sql ` SELECT version FROM settings WHERE id = 1 ` ) ;
2022-11-26 21:31:00 +00:00
if ( settingsrow . length == 0 ) {
version = 0 ;
} else {
version = settingsrow [ 0 ] . version ;
2022-12-12 17:36:08 +00:00
}
2022-11-26 21:31:00 +00:00
const latestVersion = updates . length - 1 ;
if ( version === 0 ) {
2022-12-12 17:36:08 +00:00
logger . info ( "Initializing PostgreSQL database..." ) ;
2022-12-12 17:15:10 +00:00
await sql . unsafe ( schema ) ;
2022-11-26 21:31:00 +00:00
} else if ( version < latestVersion ) {
logger . info ( ` Migrating PostgreSQL database, which is currently at version ${ version } ... ` ) ;
while ( version < latestVersion ) {
2022-09-12 21:45:32 +00:00
version ++ ;
2022-11-26 21:31:00 +00:00
logger . info ( ` Running version ${ version } update script... ` ) ;
2022-12-12 17:15:10 +00:00
await sql . unsafe ( updates [ version ] ) ;
2022-09-12 21:45:32 +00:00
}
2022-11-26 21:31:00 +00:00
} else if ( version > latestVersion ) {
throw new Error ( ` PostgreSQL database is at version ${ version } , but this version of the bot only supports up to version ${ latestVersion } . ` ) ;
} else {
return ;
}
2022-12-12 17:15:10 +00:00
await sql ` INSERT INTO settings ${ sql ( { id : 1 , version : latestVersion } )} ON CONFLICT (id) DO UPDATE SET version = ${ latestVersion } ` ;
2022-11-26 21:31:00 +00:00
} ) ;
} catch ( e ) {
logger . error ( ` PostgreSQL migration failed: ${ e } ` ) ;
logger . error ( "Unable to start the bot, quitting now." ) ;
return 1 ;
2022-02-22 00:55:25 +00:00
}
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-12-12 17:15:10 +00:00
let guild ;
await sql . begin ( async ( sql ) => {
guild = ( await sql ` SELECT * FROM guilds WHERE guild_id = ${ query } ` ) [ 0 ] ;
if ( guild == undefined ) {
guild = { guild _id : query , prefix : process . env . PREFIX , disabled : [ ] , disabled _commands : [ ] } ;
await sql ` INSERT INTO guilds ${ sql ( guild ) } ` ;
2022-12-12 17:36:08 +00:00
}
2022-12-12 17:15:10 +00:00
} ) ;
return guild ;
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 stop ( ) {
2022-09-12 21:45:32 +00:00
await sql . end ( ) ;
2022-01-07 17:44:18 +00:00
}