diff --git a/breadbot_test.db b/breadbot_test.db index 5dbfce2..2c712a5 100644 Binary files a/breadbot_test.db and b/breadbot_test.db differ diff --git a/src/breadbot.ts b/src/breadbot.ts index c24cba1..3d4addc 100644 --- a/src/breadbot.ts +++ b/src/breadbot.ts @@ -21,9 +21,8 @@ if (config.DB_MODE == "sqlite") { db.run("PRAGMA foreign_keys = ON") utilities.tables.makeTables(db) - utilities.tables.makeConstraints(db) - - //I really don't want this to be here. + + //TODO I really don't want this to be here. utilities.events.messages.setupMessageCapture(client, db) } diff --git a/src/utilties/discord/messages.ts b/src/utilties/discord/messages.ts index fe01049..d580845 100644 --- a/src/utilties/discord/messages.ts +++ b/src/utilties/discord/messages.ts @@ -1,8 +1,10 @@ -import { Message, OmitPartialGroupDMChannel } from "discord.js"; +import { Message, OmitPartialGroupDMChannel, PartialMessage } from "discord.js"; import { SQLCommon } from "../storage/interfaces"; import { SQLResult } from "../storage/enumerations"; -export async function doesMessageExist(db: SQLCommon, message: OmitPartialGroupDMChannel>) : Promise { +// TODO Do partial messages affect other functionality elsewhere? + +export async function doesMessageExist(db: SQLCommon, message: OmitPartialGroupDMChannel> | PartialMessage) : Promise { const queryResult: Object[] = await db.getAllParameterized( "SELECT * FROM messages WHERE message_snowflake = ?", [message.id] @@ -31,4 +33,48 @@ export async function insertMessage(db: SQLCommon, message: OmitPartialGroupDMCh console.log(err) return SQLResult.FAILED } +} + +export async function updateMessageContentHistory(db: SQLCommon, message: OmitPartialGroupDMChannel>) : Promise { + const messageIDExists: boolean = await doesMessageExist(db, message) + + if(!messageIDExists) { + return SQLResult.FAILED + } + + try { + await db.runParameterized( + "INSERT INTO message_content_changes (message_snowflake, message_change_old_timestamp, message_change_old_content) " + + "SELECT message_snowflake, message_timestamp, message_content FROM messages WHERE message_snowflake = ?;" + + "UPDATE messages SET message_timestamp = ?, message_content = ? WHERE message_snowflake = ?;", + [message.id, message.editedTimestamp, message.content, message.id] + ) + + return SQLResult.UPDATED + } catch (err) { + //TODO Winston should handle this + console.log(err) + return SQLResult.FAILED + } +} + +export async function markMessageDeleted(db: SQLCommon, message: OmitPartialGroupDMChannel> | PartialMessage) : Promise { + const messageIDExists: boolean = await doesMessageExist(db, message) + + if(!messageIDExists) { + return SQLResult.FAILED + } + + try { + await db.runParameterized( + "UPDATE messages SET message_deleted = 1 WHERE message_snowflake = ?", + [message.id] + ) + + return SQLResult.UPDATED + } catch (err) { + // TODO Winston should handle this + console.log(err) + return SQLResult.FAILED + } } \ No newline at end of file diff --git a/src/utilties/events/messages.ts b/src/utilties/events/messages.ts index d9ed299..fbe5c19 100644 --- a/src/utilties/events/messages.ts +++ b/src/utilties/events/messages.ts @@ -1,14 +1,22 @@ -import { Client, Events, Message, OmitPartialGroupDMChannel } from "discord.js"; +import { Client, Events, Message, messageLink, OmitPartialGroupDMChannel, PartialMessage } from "discord.js"; import { SQLResult } from "../storage/enumerations"; import { SQLCommon } from "../storage/interfaces"; import { insertChannel } from "../discord/channels"; import { insertUser } from "../discord/users"; -import { insertMessage } from "../discord/messages"; +import { doesMessageExist, insertMessage, markMessageDeleted, updateMessageContentHistory } from "../discord/messages"; export function setupMessageCapture(client: Client, db: SQLCommon) { client.on(Events.MessageCreate, async (message) => { processMessageCreate(db, message) }) + + client.on(Events.MessageUpdate, async (oldMessage, newMessage) => { + await processMessageModify(db, newMessage) + }) + + client.on(Events.MessageDelete, async (deletedMessage) => { + await processMessageDeleted(db, deletedMessage) + }) } async function processMessageCreate(db: SQLCommon, message: OmitPartialGroupDMChannel>) { @@ -20,4 +28,12 @@ async function processMessageCreate(db: SQLCommon, message: OmitPartialGroupDMCh await insertMessage(db, message) } +} + +async function processMessageModify(db: SQLCommon, newMessage: OmitPartialGroupDMChannel>) { + await updateMessageContentHistory(db, newMessage) +} + +async function processMessageDeleted(db: SQLCommon, deletedMessage: OmitPartialGroupDMChannel> | PartialMessage) { + await markMessageDeleted(db, deletedMessage) } \ No newline at end of file diff --git a/src/utilties/storage/sqlite.ts b/src/utilties/storage/sqlite.ts index 33cc857..3f7a3e6 100644 --- a/src/utilties/storage/sqlite.ts +++ b/src/utilties/storage/sqlite.ts @@ -11,17 +11,13 @@ export class SqliteDB implements SQLCommon { async run(query: string): Promise { return new Promise((resolve, reject) => { - this.db.run(query, (result : sqlite3.RunResult, err: Error) => { + this.db.run(query, function (this : sqlite3.RunResult, err: Error) { if (err) { // TODO Winston should handle this console.log(err) throw err } else { - if (result != null) { - resolve(result.changes) - } else { - resolve(0) - } + resolve(this.changes) } }) }) @@ -29,17 +25,13 @@ export class SqliteDB implements SQLCommon { async runParameterized(query: string, parameters: any[]): Promise { return new Promise((resolve, reject) => { - this.db.run(query, parameters, (result : sqlite3.RunResult, err: Error) => { + this.db.run(query, parameters, function (this : sqlite3.RunResult, err: Error) { if (err) { // TODO Winston should handle this console.log(err) throw err } else { - if (result != null) { - resolve(result.changes) - } else { - resolve(0) - } + resolve(this.changes) } }) }) diff --git a/src/utilties/storage/tables.ts b/src/utilties/storage/tables.ts index 1d87112..28d53eb 100644 --- a/src/utilties/storage/tables.ts +++ b/src/utilties/storage/tables.ts @@ -2,10 +2,10 @@ import { SQLCommon } from "./interfaces"; 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 channels (channel_snowflake bigint NOT NULL PRIMARY KEY,server_snowflake bigint,channel_name text,is_thread bit NOT NULL,is_dm bit NOT NULL);", - "CREATE TABLE users (user_snowflake bigint NOT NULL PRIMARY KEY,user_name text NOT NULL,user_displayname text);", + "CREATE TABLE IF NOT EXISTS channels (channel_snowflake bigint NOT NULL PRIMARY KEY,server_snowflake bigint,channel_name text,is_thread bit NOT NULL,is_dm bit NOT NULL);", + "CREATE TABLE IF NOT EXISTS users (user_snowflake bigint NOT NULL PRIMARY KEY,user_name text NOT NULL,user_displayname text);", "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_content_changes (message_change_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,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);" ]