2022-08-30 15:00:58 +00:00
|
|
|
|
using MySqlConnector;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
2023-02-23 21:46:49 +00:00
|
|
|
|
using System.Dynamic;
|
2022-08-30 15:00:58 +00:00
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Text.Json;
|
2023-07-23 21:31:13 +00:00
|
|
|
|
using System.Threading.Channels;
|
2022-08-30 15:00:58 +00:00
|
|
|
|
|
2023-02-23 21:46:49 +00:00
|
|
|
|
namespace SharpChat.EventStorage
|
|
|
|
|
{
|
2023-02-10 06:07:59 +00:00
|
|
|
|
public partial class MariaDBEventStorage : IEventStorage {
|
|
|
|
|
private string ConnectionString { get; }
|
2022-08-30 15:00:58 +00:00
|
|
|
|
|
2023-02-10 06:07:59 +00:00
|
|
|
|
public MariaDBEventStorage(string connString) {
|
|
|
|
|
ConnectionString = connString ?? throw new ArgumentNullException(nameof(connString));
|
2022-08-30 15:00:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-07-23 21:31:13 +00:00
|
|
|
|
public void AddEvent(
|
|
|
|
|
long id, string type,
|
|
|
|
|
object data = null,
|
|
|
|
|
StoredEventFlags flags = StoredEventFlags.None
|
|
|
|
|
) {
|
|
|
|
|
AddEvent(id, type, null, 0, null, ChatColour.None, 0, null, 0, data, flags);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void AddEvent(
|
|
|
|
|
long id, string type,
|
|
|
|
|
string channelName,
|
|
|
|
|
object data = null,
|
|
|
|
|
StoredEventFlags flags = StoredEventFlags.None
|
|
|
|
|
) {
|
|
|
|
|
AddEvent(id, type, channelName, 0, null, ChatColour.None, 0, null, 0, data, flags);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void AddEvent(
|
|
|
|
|
long id, string type,
|
|
|
|
|
long senderId, string senderName, ChatColour senderColour, int senderRank, string senderNick, ChatUserPermissions senderPerms,
|
|
|
|
|
object data = null,
|
|
|
|
|
StoredEventFlags flags = StoredEventFlags.None
|
|
|
|
|
) {
|
|
|
|
|
AddEvent(id, type, null, senderId, senderName, senderColour, senderRank, senderNick, senderPerms, data, flags);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void AddEvent(
|
|
|
|
|
long id, string type,
|
|
|
|
|
string channelName,
|
|
|
|
|
long senderId, string senderName, ChatColour senderColour, int senderRank, string senderNick, ChatUserPermissions senderPerms,
|
|
|
|
|
object data = null,
|
|
|
|
|
StoredEventFlags flags = StoredEventFlags.None
|
|
|
|
|
) {
|
2023-02-23 21:46:49 +00:00
|
|
|
|
if(type == null)
|
|
|
|
|
throw new ArgumentNullException(nameof(type));
|
2022-08-30 15:00:58 +00:00
|
|
|
|
|
|
|
|
|
RunCommand(
|
2023-02-08 03:17:07 +00:00
|
|
|
|
"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`)"
|
2023-02-23 21:46:49 +00:00
|
|
|
|
+ " VALUES (@id, NOW(), @type, @target, @flags, @data"
|
2023-02-08 03:17:07 +00:00
|
|
|
|
+ ", @sender, @sender_name, @sender_colour, @sender_rank, @sender_nick, @sender_perms)",
|
2023-02-23 21:46:49 +00:00
|
|
|
|
new MySqlParameter("id", id),
|
|
|
|
|
new MySqlParameter("type", type),
|
2023-07-23 21:31:13 +00:00
|
|
|
|
new MySqlParameter("target", string.IsNullOrWhiteSpace(channelName) ? null : channelName),
|
2023-02-23 21:46:49 +00:00
|
|
|
|
new MySqlParameter("flags", (byte)flags),
|
|
|
|
|
new MySqlParameter("data", data == null ? "{}" : JsonSerializer.SerializeToUtf8Bytes(data)),
|
2023-07-23 21:31:13 +00:00
|
|
|
|
new MySqlParameter("sender", senderId < 1 ? null : senderId),
|
|
|
|
|
new MySqlParameter("sender_name", string.IsNullOrWhiteSpace(senderName) ? null : senderName),
|
|
|
|
|
new MySqlParameter("sender_colour", senderColour.ToMisuzu()),
|
|
|
|
|
new MySqlParameter("sender_rank", senderRank),
|
|
|
|
|
new MySqlParameter("sender_nick", string.IsNullOrWhiteSpace(senderNick) ? null : senderNick),
|
|
|
|
|
new MySqlParameter("sender_perms", senderPerms)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public long AddEvent(string type, ChatUser user, ChatChannel channel, object data = null, StoredEventFlags flags = StoredEventFlags.None) {
|
|
|
|
|
if(type == null)
|
|
|
|
|
throw new ArgumentNullException(nameof(type));
|
|
|
|
|
|
|
|
|
|
long id = SharpId.Next();
|
|
|
|
|
|
|
|
|
|
AddEvent(
|
|
|
|
|
id, type,
|
|
|
|
|
channel?.Name,
|
|
|
|
|
user?.UserId ?? 0,
|
|
|
|
|
user?.UserName,
|
|
|
|
|
user?.Colour ?? ChatColour.None,
|
|
|
|
|
user?.Rank ?? 0,
|
|
|
|
|
user?.NickName,
|
|
|
|
|
user?.Permissions ?? 0,
|
|
|
|
|
data,
|
|
|
|
|
flags
|
2022-08-30 15:00:58 +00:00
|
|
|
|
);
|
2023-02-23 21:46:49 +00:00
|
|
|
|
|
|
|
|
|
return id;
|
2022-08-30 15:00:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-02-23 21:46:49 +00:00
|
|
|
|
public StoredEventInfo GetEvent(long seqId) {
|
2023-02-10 06:07:59 +00:00
|
|
|
|
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`"
|
2023-02-23 21:46:49 +00:00
|
|
|
|
+ ", UNIX_TIMESTAMP(`event_deleted`) AS `event_deleted`"
|
2023-02-10 06:07:59 +00:00
|
|
|
|
+ " FROM `sqc_events`"
|
|
|
|
|
+ " WHERE `event_id` = @id",
|
|
|
|
|
new MySqlParameter("id", seqId)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
while(reader.Read()) {
|
2023-02-23 21:46:49 +00:00
|
|
|
|
StoredEventInfo evt = ReadEvent(reader);
|
2023-02-10 06:07:59 +00:00
|
|
|
|
if(evt != null)
|
|
|
|
|
return evt;
|
|
|
|
|
}
|
|
|
|
|
} catch(MySqlException ex) {
|
|
|
|
|
Logger.Write(ex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
2022-08-30 15:00:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-02-23 21:46:49 +00:00
|
|
|
|
private static StoredEventInfo ReadEvent(MySqlDataReader reader) {
|
|
|
|
|
return new StoredEventInfo(
|
|
|
|
|
reader.GetInt64("event_id"),
|
|
|
|
|
Encoding.ASCII.GetString((byte[])reader["event_type"]),
|
|
|
|
|
reader.IsDBNull(reader.GetOrdinal("event_sender")) ? null : new ChatUser(
|
2023-02-22 00:28:53 +00:00
|
|
|
|
reader.GetInt64("event_sender"),
|
|
|
|
|
reader.GetString("event_sender_name"),
|
|
|
|
|
ChatColour.FromMisuzu(reader.GetInt32("event_sender_colour")),
|
|
|
|
|
reader.GetInt32("event_sender_rank"),
|
|
|
|
|
(ChatUserPermissions)reader.GetInt32("event_sender_perms"),
|
|
|
|
|
reader.IsDBNull(reader.GetOrdinal("event_sender_nick")) ? null : reader.GetString("event_sender_nick")
|
2023-02-23 21:46:49 +00:00
|
|
|
|
),
|
|
|
|
|
DateTimeOffset.FromUnixTimeSeconds(reader.GetInt32("event_created")),
|
|
|
|
|
reader.IsDBNull(reader.GetOrdinal("event_deleted")) ? null : DateTimeOffset.FromUnixTimeSeconds(reader.GetInt32("event_deleted")),
|
|
|
|
|
reader.IsDBNull(reader.GetOrdinal("event_target")) ? null : Encoding.ASCII.GetString((byte[])reader["event_target"]),
|
|
|
|
|
JsonDocument.Parse(Encoding.ASCII.GetString((byte[])reader["event_data"])),
|
|
|
|
|
(StoredEventFlags)reader.GetByte("event_flags")
|
|
|
|
|
);
|
2022-08-30 15:00:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-02-23 21:46:49 +00:00
|
|
|
|
public IEnumerable<StoredEventInfo> GetChannelEventLog(string channelName, int amount = 20, int offset = 0) {
|
|
|
|
|
List<StoredEventInfo> events = new();
|
2022-08-30 15:00:58 +00:00
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
using MySqlDataReader reader = RunQuery(
|
2023-02-10 06:07:59 +00:00
|
|
|
|
"SELECT `event_id`, `event_type`, `event_flags`, `event_data`, `event_target`"
|
2023-02-08 03:17:07 +00:00
|
|
|
|
+ ", `event_sender`, `event_sender_name`, `event_sender_colour`, `event_sender_rank`, `event_sender_nick`, `event_sender_perms`"
|
|
|
|
|
+ ", UNIX_TIMESTAMP(`event_created`) AS `event_created`"
|
2023-02-23 21:46:49 +00:00
|
|
|
|
+ ", UNIX_TIMESTAMP(`event_deleted`) AS `event_deleted`"
|
2023-02-08 03:17:07 +00:00
|
|
|
|
+ " FROM `sqc_events`"
|
2023-07-23 21:31:13 +00:00
|
|
|
|
+ " WHERE `event_deleted` IS NULL AND (`event_target` = @target OR `event_target` IS NULL)"
|
2023-02-08 03:17:07 +00:00
|
|
|
|
+ " AND `event_id` > @offset"
|
|
|
|
|
+ " ORDER BY `event_id` DESC"
|
|
|
|
|
+ " LIMIT @amount",
|
2023-02-16 22:47:30 +00:00
|
|
|
|
new MySqlParameter("target", channelName),
|
2023-02-08 03:17:07 +00:00
|
|
|
|
new MySqlParameter("amount", amount),
|
|
|
|
|
new MySqlParameter("offset", offset)
|
2022-08-30 15:00:58 +00:00
|
|
|
|
);
|
|
|
|
|
|
2023-02-07 15:01:56 +00:00
|
|
|
|
while(reader.Read()) {
|
2023-02-23 21:46:49 +00:00
|
|
|
|
StoredEventInfo evt = ReadEvent(reader);
|
2023-02-07 15:01:56 +00:00
|
|
|
|
if(evt != null)
|
2022-08-30 15:00:58 +00:00
|
|
|
|
events.Add(evt);
|
|
|
|
|
}
|
|
|
|
|
} catch(MySqlException ex) {
|
|
|
|
|
Logger.Write(ex);
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-10 06:18:38 +00:00
|
|
|
|
events.Reverse();
|
|
|
|
|
|
2022-08-30 15:00:58 +00:00
|
|
|
|
return events;
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-23 21:46:49 +00:00
|
|
|
|
public void RemoveEvent(StoredEventInfo evt) {
|
2023-02-10 06:07:59 +00:00
|
|
|
|
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",
|
2023-02-23 21:46:49 +00:00
|
|
|
|
new MySqlParameter("id", evt.Id)
|
2023-02-10 06:07:59 +00:00
|
|
|
|
);
|
2022-08-30 15:00:58 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|