129 lines
6 KiB
C#
129 lines
6 KiB
C#
using MySqlConnector;
|
|
using SharpChat.Events;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
|
|
namespace SharpChat.EventStorage {
|
|
public partial class MariaDBEventStorage : IEventStorage {
|
|
private string ConnectionString { get; }
|
|
|
|
public MariaDBEventStorage(string connString) {
|
|
ConnectionString = connString ?? throw new ArgumentNullException(nameof(connString));
|
|
}
|
|
|
|
public void AddEvent(IChatEvent evt) {
|
|
if(evt == null)
|
|
throw new ArgumentNullException(nameof(evt));
|
|
|
|
if(evt.SequenceId < 1)
|
|
evt.SequenceId = SharpId.Next();
|
|
|
|
RunCommand(
|
|
"INSERT INTO `sqc_events` (`event_id`, `event_created`, `event_type`, `event_target`, `event_flags`, `event_data`"
|
|
+ ", `event_sender`, `event_sender_name`, `event_sender_colour`, `event_sender_rank`, `event_sender_nick`, `event_sender_perms`)"
|
|
+ " VALUES (@id, FROM_UNIXTIME(@created), @type, @target, @flags, @data"
|
|
+ ", @sender, @sender_name, @sender_colour, @sender_rank, @sender_nick, @sender_perms)",
|
|
new MySqlParameter("id", evt.SequenceId),
|
|
new MySqlParameter("created", evt.DateTime.ToUnixTimeSeconds()),
|
|
new MySqlParameter("type", evt.GetType().FullName),
|
|
new MySqlParameter("target", evt.Target.TargetName),
|
|
new MySqlParameter("flags", (byte)evt.Flags),
|
|
new MySqlParameter("data", JsonSerializer.SerializeToUtf8Bytes(evt, evt.GetType())),
|
|
new MySqlParameter("sender", evt.Sender?.UserId < 1 ? null : (long?)evt.Sender.UserId),
|
|
new MySqlParameter("sender_name", evt.Sender?.Username),
|
|
new MySqlParameter("sender_colour", evt.Sender?.Colour.ToMisuzu()),
|
|
new MySqlParameter("sender_rank", evt.Sender?.Rank),
|
|
new MySqlParameter("sender_nick", evt.Sender?.Nickname),
|
|
new MySqlParameter("sender_perms", evt.Sender?.Permissions)
|
|
);
|
|
}
|
|
|
|
public IChatEvent GetEvent(long seqId) {
|
|
try {
|
|
using MySqlDataReader reader = RunQuery(
|
|
"SELECT `event_id`, `event_type`, `event_flags`, `event_data`, `event_target`"
|
|
+ ", `event_sender`, `event_sender_name`, `event_sender_colour`, `event_sender_rank`, `event_sender_nick`, `event_sender_perms`"
|
|
+ ", UNIX_TIMESTAMP(`event_created`) AS `event_created`"
|
|
+ " FROM `sqc_events`"
|
|
+ " WHERE `event_id` = @id",
|
|
new MySqlParameter("id", seqId)
|
|
);
|
|
|
|
while(reader.Read()) {
|
|
IChatEvent evt = ReadEvent(reader);
|
|
if(evt != null)
|
|
return evt;
|
|
}
|
|
} catch(MySqlException ex) {
|
|
Logger.Write(ex);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private static IChatEvent ReadEvent(MySqlDataReader reader) {
|
|
Type evtType = Type.GetType(Encoding.ASCII.GetString((byte[])reader["event_type"]));
|
|
IChatEvent evt = JsonSerializer.Deserialize(Encoding.ASCII.GetString((byte[])reader["event_data"]), evtType) as IChatEvent;
|
|
evt.SequenceId = reader.GetInt64("event_id");
|
|
evt.TargetName = Encoding.ASCII.GetString((byte[])reader["event_target"]);
|
|
evt.Flags = (ChatMessageFlags)reader.GetByte("event_flags");
|
|
evt.DateTime = DateTimeOffset.FromUnixTimeSeconds(reader.GetInt32("event_created"));
|
|
|
|
if(!reader.IsDBNull(reader.GetOrdinal("event_sender"))) {
|
|
evt.Sender = new BasicUser {
|
|
UserId = reader.GetInt64("event_sender"),
|
|
Username = reader.GetString("event_sender_name"),
|
|
Colour = ChatColour.FromMisuzu(reader.GetInt32("event_sender_colour")),
|
|
Rank = reader.GetInt32("event_sender_rank"),
|
|
Nickname = reader.IsDBNull(reader.GetOrdinal("event_sender_nick")) ? null : reader.GetString("event_sender_nick"),
|
|
Permissions = (ChatUserPermissions)reader.GetInt32("event_sender_perms")
|
|
};
|
|
}
|
|
|
|
return evt;
|
|
}
|
|
|
|
public IEnumerable<IChatEvent> GetTargetEventLog(string target, int amount = 20, int offset = 0) {
|
|
List<IChatEvent> events = new();
|
|
|
|
try {
|
|
using MySqlDataReader reader = RunQuery(
|
|
"SELECT `event_id`, `event_type`, `event_flags`, `event_data`, `event_target`"
|
|
+ ", `event_sender`, `event_sender_name`, `event_sender_colour`, `event_sender_rank`, `event_sender_nick`, `event_sender_perms`"
|
|
+ ", UNIX_TIMESTAMP(`event_created`) AS `event_created`"
|
|
+ " FROM `sqc_events`"
|
|
+ " WHERE `event_deleted` IS NULL AND `event_target` = @target"
|
|
+ " AND `event_id` > @offset"
|
|
+ " ORDER BY `event_id` DESC"
|
|
+ " LIMIT @amount",
|
|
new MySqlParameter("target", target),
|
|
new MySqlParameter("amount", amount),
|
|
new MySqlParameter("offset", offset)
|
|
);
|
|
|
|
while(reader.Read()) {
|
|
IChatEvent evt = ReadEvent(reader);
|
|
if(evt != null)
|
|
events.Add(evt);
|
|
}
|
|
} catch(MySqlException ex) {
|
|
Logger.Write(ex);
|
|
}
|
|
|
|
events.Reverse();
|
|
|
|
return events;
|
|
}
|
|
|
|
public void RemoveEvent(IChatEvent evt) {
|
|
if(evt == null)
|
|
throw new ArgumentNullException(nameof(evt));
|
|
RunCommand(
|
|
"UPDATE IGNORE `sqc_events` SET `event_deleted` = NOW() WHERE `event_id` = @id AND `event_deleted` IS NULL",
|
|
new MySqlParameter("id", evt.SequenceId)
|
|
);
|
|
}
|
|
}
|
|
}
|