PluralKit/PluralKit.Core/Database/Repository/ModelRepository.Message.cs

74 lines
3.1 KiB
C#
Raw Normal View History

2021-08-27 15:03:47 +00:00
using System.Collections.Generic;
2020-08-29 11:46:27 +00:00
using System.Linq;
using System.Threading.Tasks;
using Dapper;
using SqlKata;
2020-08-29 11:46:27 +00:00
namespace PluralKit.Core
{
public partial class ModelRepository
{
public Task AddMessage(PKMessage msg)
2021-08-27 15:03:47 +00:00
{
var query = new Query("messages").AsInsert(new
{
mid = msg.Mid,
guild = msg.Guild,
channel = msg.Channel,
member = msg.Member,
sender = msg.Sender,
original_mid = msg.OriginalMid,
});
2020-08-29 11:46:27 +00:00
_logger.Debug("Stored message {@StoredMessage} in channel {Channel}", msg, msg.Channel);
// "on conflict do nothing" in the (pretty rare) case of duplicate events coming in from Discord, which would lead to a DB error before
return _db.ExecuteQuery(query, extraSql: "on conflict do nothing");
2020-08-29 11:46:27 +00:00
}
2021-08-27 15:03:47 +00:00
// todo: add a Mapper to QuerySingle and move this to SqlKata
public async Task<FullMessage?> GetMessage(IPKConnection conn, ulong id)
2020-08-29 11:46:27 +00:00
{
FullMessage Mapper(PKMessage msg, PKMember member, PKSystem system) =>
2021-08-27 15:03:47 +00:00
new FullMessage { Message = msg, System = system, Member = member };
2020-08-29 11:46:27 +00:00
var result = await conn.QueryAsync<PKMessage, PKMember, PKSystem, FullMessage>(
"select messages.*, members.*, systems.* from messages, members, systems where (mid = @Id or original_mid = @Id) and messages.member = members.id and systems.id = members.system",
2021-08-27 15:03:47 +00:00
Mapper, new { Id = id });
2020-08-29 11:46:27 +00:00
return result.FirstOrDefault();
}
public async Task DeleteMessage(ulong id)
2020-08-29 11:46:27 +00:00
{
var query = new Query("messages").AsDelete().Where("mid", id);
var rowCount = await _db.ExecuteQuery(query);
2020-08-29 11:46:27 +00:00
if (rowCount > 0)
_logger.Information("Deleted message {MessageId} from database", id);
}
public async Task DeleteMessagesBulk(IReadOnlyCollection<ulong> ids)
2020-08-29 11:46:27 +00:00
{
// Npgsql doesn't support ulongs in general - we hacked around it for plain ulongs but tbh not worth it for collections of ulong
// Hence we map them to single longs, which *are* supported (this is ok since they're Technically (tm) stored as signed longs in the db anyway)
var query = new Query("messages").AsDelete().WhereIn("mid", ids.Select(id => (long)id).ToArray());
var rowCount = await _db.ExecuteQuery(query);
2020-08-29 11:46:27 +00:00
if (rowCount > 0)
_logger.Information("Bulk deleted messages ({FoundCount} found) from database: {MessageIds}", rowCount,
ids);
}
public Task<PKMessage?> GetLastMessage(ulong guildId, ulong channelId, ulong accountId)
{
// Want to index scan on the (guild, sender, mid) index so need the additional constraint
var query = new Query("messages")
.Where("guild", guildId)
.Where("channel", channelId)
.Where("sender", accountId)
.OrderByDesc("mid")
.Limit(1);
return _db.QueryFirst<PKMessage?>(query);
}
2020-08-29 11:46:27 +00:00
}
}