diff --git a/Catalogger.Backend/Bot/Commands/KeyRoleCommands.cs b/Catalogger.Backend/Bot/Commands/KeyRoleCommands.cs index df2493d..977e016 100644 --- a/Catalogger.Backend/Bot/Commands/KeyRoleCommands.cs +++ b/Catalogger.Backend/Bot/Commands/KeyRoleCommands.cs @@ -50,7 +50,7 @@ public class KeyRoleCommands( var guildRoles = roleCache.GuildRoles(guildId).ToList(); var guildConfig = await db.GetGuildAsync(guildId); - if (guildConfig.KeyRoles.Count == 0) + if (guildConfig.KeyRoles.Length == 0) return await feedbackService.ReplyAsync( "There are no key roles to list. Add some with `/key-roles add`.", isEphemeral: true @@ -92,7 +92,7 @@ public class KeyRoleCommands( isEphemeral: true ); - guildConfig.KeyRoles.Add(role.ID.Value); + guildConfig.KeyRoles = guildConfig.KeyRoles.Append(role.ID.Value).ToArray(); db.Update(guildConfig); await db.SaveChangesAsync(); @@ -117,7 +117,7 @@ public class KeyRoleCommands( isEphemeral: true ); - guildConfig.KeyRoles.Remove(role.ID.Value); + guildConfig.KeyRoles = guildConfig.KeyRoles.Except([role.ID.Value]).ToArray(); db.Update(guildConfig); await db.SaveChangesAsync(); diff --git a/Catalogger.Backend/Database/Dapper/DatabasePool.cs b/Catalogger.Backend/Database/Dapper/DatabasePool.cs index 7c7bf35..98296f1 100644 --- a/Catalogger.Backend/Database/Dapper/DatabasePool.cs +++ b/Catalogger.Backend/Database/Dapper/DatabasePool.cs @@ -14,6 +14,9 @@ // along with this program. If not, see . using System.Data; +using System.Text.Json; +using System.Text.Json.Serialization; +using Catalogger.Backend.Database.Models; using Dapper; using NodaTime; using Npgsql; @@ -113,6 +116,7 @@ public class DatabasePool SqlMapper.AddTypeHandler(new UlongArrayHandler()); SqlMapper.AddTypeHandler(new PassthroughTypeHandler()); + SqlMapper.AddTypeHandler(new JsonTypeHandler()); } // Copied from PluralKit: @@ -144,6 +148,21 @@ public class DatabasePool public override ulong[] Parse(object value) => Array.ConvertAll((long[])value, i => (ulong)i); } + + public class JsonTypeHandler : SqlMapper.TypeHandler + { + public override T Parse(object value) + { + string json = (string)value; + return JsonSerializer.Deserialize(json) + ?? throw new CataloggerError("JsonTypeHandler returned null"); + } + + public override void SetValue(IDbDataParameter parameter, T? value) + { + parameter.Value = JsonSerializer.Serialize(value); + } + } } public static class ServiceCollectionDatabaseExtensions diff --git a/Catalogger.Backend/Database/DatabaseContext.cs b/Catalogger.Backend/Database/DatabaseContext.cs index 0e2c704..0fa4fb4 100644 --- a/Catalogger.Backend/Database/DatabaseContext.cs +++ b/Catalogger.Backend/Database/DatabaseContext.cs @@ -74,12 +74,18 @@ public class DatabaseContext : DbContext c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())) ); + private static readonly ValueComparer UlongArrayValueComparer = + new( + (c1, c2) => c1 != null && c2 != null && c1.SequenceEqual(c2), + c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())) + ); + protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder .Entity() .Property(g => g.KeyRoles) - .Metadata.SetValueComparer(UlongListValueComparer); + .Metadata.SetValueComparer(UlongArrayValueComparer); modelBuilder.Entity().HasKey(i => i.Code); modelBuilder.Entity().HasIndex(i => i.GuildId); diff --git a/Catalogger.Backend/Database/Models/Guild.cs b/Catalogger.Backend/Database/Models/Guild.cs index 4ed7836..9ac8042 100644 --- a/Catalogger.Backend/Database/Models/Guild.cs +++ b/Catalogger.Backend/Database/Models/Guild.cs @@ -27,8 +27,8 @@ public class Guild [Column(TypeName = "jsonb")] public ChannelConfig Channels { get; init; } = new(); - public List BannedSystems { get; init; } = []; - public List KeyRoles { get; init; } = []; + public string[] BannedSystems { get; set; } = []; + public ulong[] KeyRoles { get; set; } = []; public bool IsSystemBanned(PluralkitApiService.PkSystem system) => BannedSystems.Contains(system.Id) || BannedSystems.Contains(system.Uuid.ToString());