SupportChild/Database/Ticket.cs
Toastie 4cbcf0b65e
All checks were successful
toastie-stuff/SupportChild/pipeline/head This commit looks good
Refactored and split up the database class
2025-02-06 15:15:18 +13:00

312 lines
No EOL
10 KiB
C#

using System.Collections.Generic;
using DSharpPlus;
using MySqlConnector;
namespace SupportChild.Database;
public class Ticket(MySqlDataReader reader)
{
public readonly uint id = reader.GetUInt32("id");
public readonly ulong creatorID = reader.GetUInt64("creator_id");
public readonly ulong assignedStaffID = reader.GetUInt64("assigned_staff_id");
public readonly string summary = reader.GetString("summary");
public readonly ulong channelID = reader.GetUInt64("channel_id");
public string DiscordRelativeTime()
{
return Formatter.Timestamp(channelID.GetSnowflakeTime(), Config.timestampFormat);
}
public static long GetNumberOfTickets()
{
try
{
using MySqlConnection c = Connection.GetConnection();
using MySqlCommand countTickets = new MySqlCommand("SELECT COUNT(*) FROM tickets", c);
c.Open();
return (long)(countTickets?.ExecuteScalar() ?? 0);
}
catch (MySqlException e)
{
Logger.Error("Error occured when attempting to count number of open tickets.", e);
}
return -1;
}
public static long GetNumberOfClosedTickets()
{
try
{
using MySqlConnection c = Connection.GetConnection();
using MySqlCommand countTickets = new MySqlCommand("SELECT COUNT(*) FROM ticket_history", c);
c.Open();
return (long)(countTickets?.ExecuteScalar() ?? 0);
}
catch (MySqlException e)
{
Logger.Error("Error occured when attempting to count number of open tickets.", e);
}
return -1;
}
public static bool IsOpenTicket(ulong channelID)
{
using MySqlConnection c = Connection.GetConnection();
c.Open();
using MySqlCommand selection = new("SELECT * FROM tickets WHERE channel_id=@channel_id", c);
selection.Parameters.AddWithValue("@channel_id", channelID);
selection.Prepare();
MySqlDataReader results = selection.ExecuteReader();
// Check if ticket exists in the database
if (!results.Read())
{
return false;
}
results.Close();
return true;
}
public static bool TryGetOpenTicket(ulong channelID, out Ticket ticket)
{
using MySqlConnection c = Connection.GetConnection();
c.Open();
using MySqlCommand selection = new("SELECT * FROM tickets WHERE channel_id=@channel_id", c);
selection.Parameters.AddWithValue("@channel_id", channelID);
selection.Prepare();
MySqlDataReader results = selection.ExecuteReader();
// Check if ticket exists in the database
if (!results.Read())
{
ticket = null;
return false;
}
ticket = new Ticket(results);
results.Close();
return true;
}
public static bool TryGetOpenTicketByID(uint id, out Ticket ticket)
{
using MySqlConnection c = Connection.GetConnection();
c.Open();
using MySqlCommand selection = new("SELECT * FROM tickets WHERE id=@id", c);
selection.Parameters.AddWithValue("@id", id);
selection.Prepare();
MySqlDataReader results = selection.ExecuteReader();
// Check if open ticket exists in the database
if (results.Read())
{
ticket = new Ticket(results);
results.Close();
return true;
}
results.Close();
ticket = null;
return false;
}
public static bool TryGetClosedTicket(uint id, out Ticket ticket)
{
using MySqlConnection c = Connection.GetConnection();
c.Open();
using MySqlCommand selection = new("SELECT * FROM ticket_history WHERE id=@id", c);
selection.Parameters.AddWithValue("@id", id);
selection.Prepare();
MySqlDataReader results = selection.ExecuteReader();
// Check if closed ticket exists in the database
if (results.Read())
{
ticket = new Ticket(results);
results.Close();
return true;
}
ticket = null;
results.Close();
return false;
}
public static bool TryGetOpenTickets(ulong userID, out List<Ticket> tickets)
{
tickets = null;
using MySqlConnection c = Connection.GetConnection();
c.Open();
using MySqlCommand selection = new("SELECT * FROM tickets WHERE creator_id=@creator_id", c);
selection.Parameters.AddWithValue("@creator_id", userID);
selection.Prepare();
MySqlDataReader results = selection.ExecuteReader();
if (!results.Read())
{
return false;
}
tickets = [new Ticket(results)];
while (results.Read())
{
tickets.Add(new Ticket(results));
}
results.Close();
return true;
}
public static bool TryGetOpenTickets(out List<Ticket> tickets)
{
tickets = null;
using MySqlConnection c = Connection.GetConnection();
c.Open();
using MySqlCommand selection = new("SELECT * FROM tickets ORDER BY channel_id", c);
selection.Prepare();
MySqlDataReader results = selection.ExecuteReader();
if (!results.Read())
{
return false;
}
tickets = [new Ticket(results)];
while (results.Read())
{
tickets.Add(new Ticket(results));
}
results.Close();
return true;
}
public static bool TryGetClosedTickets(ulong userID, out List<Ticket> tickets)
{
tickets = null;
using MySqlConnection c = Connection.GetConnection();
c.Open();
using MySqlCommand selection = new("SELECT * FROM ticket_history WHERE creator_id=@creator_id", c);
selection.Parameters.AddWithValue("@creator_id", userID);
selection.Prepare();
MySqlDataReader results = selection.ExecuteReader();
if (!results.Read())
{
return false;
}
tickets = [new Ticket(results)];
while (results.Read())
{
tickets.Add(new Ticket(results));
}
results.Close();
return true;
}
public static bool TryGetAssignedTickets(ulong staffID, out List<Ticket> tickets)
{
tickets = null;
using MySqlConnection c = Connection.GetConnection();
c.Open();
using MySqlCommand selection = new("SELECT * FROM tickets WHERE assigned_staff_id=@assigned_staff_id", c);
selection.Parameters.AddWithValue("@assigned_staff_id", staffID);
selection.Prepare();
MySqlDataReader results = selection.ExecuteReader();
if (!results.Read())
{
return false;
}
tickets = [new Ticket(results)];
while (results.Read())
{
tickets.Add(new Ticket(results));
}
results.Close();
return true;
}
public static long NewTicket(ulong memberID, ulong staffID, ulong ticketID)
{
using MySqlConnection c = Connection.GetConnection();
c.Open();
using MySqlCommand cmd = new("INSERT INTO tickets (created_time, creator_id, assigned_staff_id, summary, channel_id) VALUES (UTC_TIMESTAMP(), @creator_id, @assigned_staff_id, @summary, @channel_id);", c);
cmd.Parameters.AddWithValue("@creator_id", memberID);
cmd.Parameters.AddWithValue("@assigned_staff_id", staffID);
cmd.Parameters.AddWithValue("@summary", "");
cmd.Parameters.AddWithValue("@channel_id", ticketID);
cmd.ExecuteNonQuery();
return cmd.LastInsertedId;
}
public static void ArchiveTicket(Ticket ticket)
{
// Check if ticket already exists in the archive
if (TryGetClosedTicket(ticket.id, out Ticket _))
{
using MySqlConnection c = Connection.GetConnection();
using MySqlCommand deleteTicket = new("DELETE FROM ticket_history WHERE id=@id OR channel_id=@channel_id", c);
deleteTicket.Parameters.AddWithValue("@id", ticket.id);
deleteTicket.Parameters.AddWithValue("@channel_id", ticket.channelID);
c.Open();
deleteTicket.Prepare();
deleteTicket.ExecuteNonQuery();
}
// Create an entry in the ticket history database
using MySqlConnection conn = Connection.GetConnection();
using MySqlCommand archiveTicket = new("INSERT INTO ticket_history (id, created_time, closed_time, creator_id, assigned_staff_id, summary, channel_id) VALUES (@id, @created_time, UTC_TIMESTAMP(), @creator_id, @assigned_staff_id, @summary, @channel_id);", conn);
archiveTicket.Parameters.AddWithValue("@id", ticket.id);
archiveTicket.Parameters.AddWithValue("@created_time", ticket.channelID.GetSnowflakeTime());
archiveTicket.Parameters.AddWithValue("@creator_id", ticket.creatorID);
archiveTicket.Parameters.AddWithValue("@assigned_staff_id", ticket.assignedStaffID);
archiveTicket.Parameters.AddWithValue("@summary", ticket.summary);
archiveTicket.Parameters.AddWithValue("@channel_id", ticket.channelID);
conn.Open();
archiveTicket.Prepare();
archiveTicket.ExecuteNonQuery();
}
public static bool DeleteOpenTicket(uint ticketID)
{
try
{
using MySqlConnection c = Connection.GetConnection();
using MySqlCommand deletion = new("DELETE FROM tickets WHERE id=@id", c);
deletion.Parameters.AddWithValue("@id", ticketID);
c.Open();
deletion.Prepare();
return deletion.ExecuteNonQuery() > 0;
}
catch (MySqlException e)
{
Logger.Warn("Could not delete open ticket in database.", e);
return false;
}
}
public static bool SetSummary(ulong channelID, string summary)
{
try
{
using MySqlConnection c = Connection.GetConnection();
c.Open();
using MySqlCommand update = new("UPDATE tickets SET summary = @summary WHERE channel_id = @channel_id", c);
update.Parameters.AddWithValue("@summary", summary);
update.Parameters.AddWithValue("@channel_id", channelID);
update.Prepare();
return update.ExecuteNonQuery() > 0;
}
catch (MySqlException e)
{
Logger.Warn("Could not set summary in database.", e);
return false;
}
}
}