A ton of fixes and it's now possible to track servers and channels in the DB
This commit is contained in:
parent
d9bcdb766c
commit
a247bfb35e
BIN
breadbot_test.db
BIN
breadbot_test.db
Binary file not shown.
@ -1,9 +1,10 @@
|
|||||||
import { Client, Events, GatewayIntentBits, Guild, Interaction } from "discord.js"
|
import { Client, Events, GatewayIntentBits, Guild, GuildBasedChannel, Interaction } from "discord.js"
|
||||||
import { utilities } from "./utilties"
|
import { utilities } from "./utilties"
|
||||||
import { commands } from "./commands"
|
import { commands } from "./commands"
|
||||||
import { config } from "./config"
|
import { config } from "./config"
|
||||||
|
import { SQLCommon } from "./utilties/storage/interfaces"
|
||||||
|
|
||||||
const client : Client = new Client({
|
export const client : Client = new Client({
|
||||||
intents: [
|
intents: [
|
||||||
GatewayIntentBits.Guilds,
|
GatewayIntentBits.Guilds,
|
||||||
GatewayIntentBits.GuildMessages,
|
GatewayIntentBits.GuildMessages,
|
||||||
@ -11,12 +12,15 @@ const client : Client = new Client({
|
|||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
let db: SQLCommon
|
||||||
|
|
||||||
if (config.DB_MODE == "sqlite") {
|
if (config.DB_MODE == "sqlite") {
|
||||||
const db = new utilities.sqlite.SqliteDB("breadbot_test.db")
|
db = new utilities.sqlite.SqliteDB("breadbot_test.db")
|
||||||
|
|
||||||
db.run("PRAGMA foreign_keys = ON")
|
db.run("PRAGMA foreign_keys = ON")
|
||||||
|
|
||||||
utilities.tables.makeTables(db)
|
utilities.tables.makeTables(db)
|
||||||
|
utilities.tables.makeConstraints(db)
|
||||||
}
|
}
|
||||||
|
|
||||||
client.once(Events.ClientReady, () => {
|
client.once(Events.ClientReady, () => {
|
||||||
@ -24,13 +28,24 @@ client.once(Events.ClientReady, () => {
|
|||||||
console.log("Breadbot is ready")
|
console.log("Breadbot is ready")
|
||||||
|
|
||||||
client.guilds.cache.forEach(async (guild: Guild) => {
|
client.guilds.cache.forEach(async (guild: Guild) => {
|
||||||
console.log(`ID: ${guild.id}, Name: ${guild.name}, Desc: ${guild.description}`)
|
await utilities.commands.deployCommands(guild.id)
|
||||||
await utilities.command.deployCommands(guild.id)
|
|
||||||
|
// TODO handle failures?
|
||||||
|
await utilities.guilds.insertGuild(db, guild)
|
||||||
|
|
||||||
|
guild.channels.cache.forEach(async (channel: GuildBasedChannel) => {
|
||||||
|
await utilities.channels.insertChannel(db, channel)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
client.on(Events.GuildCreate, async (guild : Guild) => {
|
client.on(Events.GuildCreate, async (guild : Guild) => {
|
||||||
await utilities.command.deployCommands(guild.id)
|
await utilities.commands.deployCommands(guild.id)
|
||||||
|
await utilities.guilds.insertGuild(db, guild)
|
||||||
|
|
||||||
|
guild.channels.cache.forEach(async (channel: GuildBasedChannel) => {
|
||||||
|
await utilities.channels.insertChannel(db, channel)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
client.on(Events.InteractionCreate, async (interaction: Interaction) => {
|
client.on(Events.InteractionCreate, async (interaction: Interaction) => {
|
||||||
|
33
src/utilties/discord/channels.ts
Normal file
33
src/utilties/discord/channels.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import { SQLCommon } from "../storage/interfaces";
|
||||||
|
import { GuildBasedChannel } from "discord.js";
|
||||||
|
import { SQLResult } from "../storage/enumerations";
|
||||||
|
|
||||||
|
export async function doesChannelExist(db: SQLCommon, channel : GuildBasedChannel) : Promise<boolean> {
|
||||||
|
const queryResult : Object[] = await db.getAllParameterized(
|
||||||
|
"SELECT * FROM channels WHERE server_snowflake = ? AND channel_snowflake = ?",
|
||||||
|
[channel.guild.id, channel.id]
|
||||||
|
)
|
||||||
|
|
||||||
|
return queryResult.length != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function insertChannel(db: SQLCommon, channel: GuildBasedChannel) : Promise<SQLResult> {
|
||||||
|
const alreadyExists: boolean = await doesChannelExist(db, channel)
|
||||||
|
|
||||||
|
if(alreadyExists) {
|
||||||
|
return SQLResult.ALREADYEXISTS
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await db.runParameterized(
|
||||||
|
"INSERT INTO channels VALUES (?, ?, ?, ?)",
|
||||||
|
[channel.id, channel.guild.id, channel.name, channel.isThread()]
|
||||||
|
)
|
||||||
|
|
||||||
|
return SQLResult.CREATED
|
||||||
|
} catch (err) {
|
||||||
|
//TODO Winston should handle this
|
||||||
|
console.log(err)
|
||||||
|
return SQLResult.FAILED
|
||||||
|
}
|
||||||
|
}
|
33
src/utilties/discord/guilds.ts
Normal file
33
src/utilties/discord/guilds.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import { Guild } from "discord.js";
|
||||||
|
import { SQLCommon } from "../storage/interfaces";
|
||||||
|
import { SQLResult } from "../storage/enumerations";
|
||||||
|
|
||||||
|
export async function doesGuildExist(db: SQLCommon, guild : Guild) : Promise<boolean> {
|
||||||
|
const queryResult : Object[] = await db.getAllParameterized(
|
||||||
|
"SELECT * FROM servers WHERE server_snowflake = ?",
|
||||||
|
[guild.id]
|
||||||
|
)
|
||||||
|
|
||||||
|
return queryResult.length != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function insertGuild(db: SQLCommon, guild: Guild) : Promise<SQLResult> {
|
||||||
|
const alreadyExists: boolean = await doesGuildExist(db, guild)
|
||||||
|
|
||||||
|
if (alreadyExists) {
|
||||||
|
return SQLResult.ALREADYEXISTS
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await db.runParameterized(
|
||||||
|
"INSERT INTO servers VALUES (?, ?, ?)",
|
||||||
|
[guild.id, guild.name, guild.description]
|
||||||
|
)
|
||||||
|
|
||||||
|
return SQLResult.CREATED
|
||||||
|
} catch (err) {
|
||||||
|
console.log("Insert Failed")
|
||||||
|
//TODO Winston should handle this
|
||||||
|
console.log(err)
|
||||||
|
return SQLResult.FAILED
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,13 @@
|
|||||||
import * as command from "./discord/command_utils"
|
import * as commands from "./discord/commands"
|
||||||
import * as sqlite from "./storage/sqlite"
|
import * as sqlite from "./storage/sqlite"
|
||||||
import * as tables from "./storage/tables"
|
import * as tables from "./storage/tables"
|
||||||
|
import * as guilds from "./discord/guilds"
|
||||||
|
import * as channels from "./discord/channels"
|
||||||
|
|
||||||
export const utilities = {
|
export const utilities = {
|
||||||
command,
|
commands,
|
||||||
sqlite,
|
sqlite,
|
||||||
tables
|
tables,
|
||||||
|
guilds,
|
||||||
|
channels
|
||||||
}
|
}
|
7
src/utilties/storage/enumerations.ts
Normal file
7
src/utilties/storage/enumerations.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export enum SQLResult {
|
||||||
|
CREATED,
|
||||||
|
UPDATED,
|
||||||
|
DELETED,
|
||||||
|
ALREADYEXISTS,
|
||||||
|
FAILED
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
export interface sql_common {
|
export interface SQLCommon {
|
||||||
run(query: string) : Promise<number>
|
run(query: string) : Promise<number>
|
||||||
runParameterized(query: string, parameters: any[]): Promise<number>
|
runParameterized(query: string, parameters: any[]): Promise<number>
|
||||||
getAll(query: string) : Promise<Object[]>
|
getAll(query: string) : Promise<Object[]>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import * as sqlite3 from 'sqlite3'
|
import * as sqlite3 from 'sqlite3'
|
||||||
|
|
||||||
import { sql_common } from "./interfaces"
|
import { SQLCommon } from "./interfaces"
|
||||||
|
|
||||||
export class SqliteDB implements sql_common {
|
export class SqliteDB implements SQLCommon {
|
||||||
private db : sqlite3.Database;
|
private db : sqlite3.Database;
|
||||||
|
|
||||||
public constructor(private readonly dbName: string) {
|
public constructor(private readonly dbName: string) {
|
||||||
@ -10,7 +10,7 @@ export class SqliteDB implements sql_common {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async run(query: string): Promise<number> {
|
async run(query: string): Promise<number> {
|
||||||
return new Promise(() => {
|
return new Promise((resolve, reject) => {
|
||||||
this.db.run(query, (result : sqlite3.RunResult, err: Error) => {
|
this.db.run(query, (result : sqlite3.RunResult, err: Error) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
// TODO Winston should handle this
|
// TODO Winston should handle this
|
||||||
@ -18,9 +18,9 @@ export class SqliteDB implements sql_common {
|
|||||||
throw err
|
throw err
|
||||||
} else {
|
} else {
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
return result.changes
|
resolve(result.changes)
|
||||||
} else {
|
} else {
|
||||||
return 0
|
resolve(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -28,42 +28,47 @@ export class SqliteDB implements sql_common {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async runParameterized(query: string, parameters: any[]): Promise<number> {
|
async runParameterized(query: string, parameters: any[]): Promise<number> {
|
||||||
return new Promise(() => {
|
return new Promise((resolve, reject) => {
|
||||||
this.db.run(query, parameters, (result : sqlite3.RunResult, err: Error) => {
|
this.db.run(query, parameters, (result : sqlite3.RunResult, err: Error) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
// TODO Winston should handle this
|
// TODO Winston should handle this
|
||||||
console.log(err)
|
console.log(err)
|
||||||
throw err
|
throw err
|
||||||
} else {
|
} else {
|
||||||
return result.changes
|
if (result != null) {
|
||||||
|
resolve(result.changes)
|
||||||
|
} else {
|
||||||
|
resolve(0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAll(query: string): Promise<Object[]> {
|
async getAll(query: string): Promise<Object[]> {
|
||||||
return new Promise(() => {
|
return new Promise((resolve, reject) => {
|
||||||
this.db.all(query, (err: Error, rows: Object[]) => {
|
this.db.all(query, (err: Error, rows: Object[]) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
// TODO Winston should handle this
|
// TODO Winston should handle this
|
||||||
console.log(err)
|
console.log(err)
|
||||||
throw err
|
throw err
|
||||||
} else {
|
} else {
|
||||||
return rows
|
console.log("Got rows")
|
||||||
|
resolve(rows)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
getAllParameterized(query: string, parameters: any[]): Promise<Object[]> {
|
getAllParameterized(query: string, parameters: any[]): Promise<Object[]> {
|
||||||
return new Promise(() => {
|
return new Promise((resolve, reject) => {
|
||||||
this.db.all(query, parameters, (err: Error, rows: Object[]) => {
|
this.db.all(query, parameters, (err: Error, rows: Object[]) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
// TODO Winston should handle this
|
// TODO Winston should handle this
|
||||||
console.log(err)
|
console.log(err)
|
||||||
throw err
|
throw err
|
||||||
} else {
|
} else {
|
||||||
return rows
|
resolve(rows)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -1,11 +1,22 @@
|
|||||||
import { sql_common } from "./interfaces";
|
import { SQLCommon } from "./interfaces";
|
||||||
|
|
||||||
const tables: string[] = [
|
const tables: string[] = [
|
||||||
"CREATE TABLE IF NOT EXISTS servers (server_snowflake bigint NOT NULL PRIMARY KEY,server_name text NOT NULL,server_description mediumtext);",
|
"CREATE TABLE IF NOT EXISTS servers (server_snowflake bigint NOT NULL PRIMARY KEY,server_name text NOT NULL,server_description mediumtext);",
|
||||||
"CREATE TABLE IF NOT EXISTS channels (channel_snowflake bigint NOT NULL PRIMARY KEY,server_snowflake bigint NOT NULL,channel_name text NOT NULL);"
|
"CREATE TABLE IF NOT EXISTS channels (channel_snowflake bigint NOT NULL PRIMARY KEY,server_snowflake bigint NOT NULL,channel_name text NOT NULL,is_thread bit NOT NULL);",
|
||||||
|
"CREATE TABLE IF NOT EXISTS messages (message_snowflake bigint NOT NULL PRIMARY KEY,channel_snowflake bigint NOT NULL,user_snowflake bigint NOT NULL,message_content longtext NOT NULL,message_timestamp datetime NOT NULL,message_deleted bit NOT NULL);",
|
||||||
|
"CREATE TABLE IF NOT EXISTS message_content_changes (message_change_id bigint NOT NULL PRIMARY KEY,message_snowflake bigint NOT NULL,message_change_old_timestamp datetime NOT NULL,message_change_old_content longtext NOT NULL);",
|
||||||
|
"CREATE TABLE IF NOT EXISTS message_attachments (attachment_snowflake bigint NOT NULL PRIMARY KEY,message_snowflake bigint NOT NULL,attachment_name text NOT NULL,attachment_description text,attachment_timestamp datetime NOT NULL,attachment_mime_type text,attachment_url text NOT NULL,attachment_downloaded bit NOT NULL);"
|
||||||
]
|
]
|
||||||
|
|
||||||
export async function makeTables(db: sql_common): Promise<number[]> {
|
const constraints: string[] = [
|
||||||
|
"ALTER TABLE channels ADD CONSTRAINT channels_server_snowflake_fk FOREIGN KEY (server_snowflake) REFERENCES servers (server_snowflake);"
|
||||||
|
]
|
||||||
|
|
||||||
|
export async function makeTables(db: SQLCommon): Promise<number[]> {
|
||||||
return Promise.all(tables.map((statement) => db.run(statement)))
|
return Promise.all(tables.map((statement) => db.run(statement)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function makeConstraints(db: SQLCommon): Promise<number[]> {
|
||||||
|
return Promise.all(constraints.map((statement) => db.run(statement)))
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user