From ed5cedefd2b0963d5b6c3f081b7e28def9f2df38 Mon Sep 17 00:00:00 2001 From: Infi Date: Sun, 21 Apr 2024 01:59:04 +0200 Subject: [PATCH] remove message limit text as it doesn't exist for database itself --- ChatTwo/MessageStore.cs | 160 ++++++++++++++----------- ChatTwo/Resources/Language.Designer.cs | 2 +- ChatTwo/Resources/Language.resx | 2 +- ChatTwo/Ui/SettingsTabs/Database.cs | 2 +- 4 files changed, 93 insertions(+), 73 deletions(-) diff --git a/ChatTwo/MessageStore.cs b/ChatTwo/MessageStore.cs index 611ebd3..92a1954 100644 --- a/ChatTwo/MessageStore.cs +++ b/ChatTwo/MessageStore.cs @@ -13,85 +13,98 @@ using Encoding = System.Text.Encoding; namespace ChatTwo; -internal static class DbExtensions { - internal static void Execute(this DbConnection conn, string sql) { +internal static class DbExtensions +{ + internal static void Execute(this DbConnection conn, string sql) + { using var cmd = conn.CreateCommand(); cmd.CommandText = sql; cmd.ExecuteNonQuery(); } } -internal enum PayloadMessagePackType : byte { +internal enum PayloadMessagePackType : byte +{ Achievement, PartyFinder, Uri, Other = 255, } -public class PayloadMessagePackFormatter : IMessagePackFormatter { - public void Serialize(ref MessagePackWriter writer, Payload? value, MessagePackSerializerOptions options) { - if (value == null) { +public class PayloadMessagePackFormatter : IMessagePackFormatter +{ + public void Serialize(ref MessagePackWriter writer, Payload? value, MessagePackSerializerOptions options) + { + if (value == null) + { writer.WriteNil(); return; } writer.WriteArrayHeader(2); - switch (value) { + switch (value) + { case AchievementPayload achievementPayload: - writer.WriteUInt8((byte) PayloadMessagePackType.Achievement); + writer.WriteUInt8((byte)PayloadMessagePackType.Achievement); writer.WriteUInt32(achievementPayload.Id); break; case PartyFinderPayload partyFinderPayload: - writer.WriteUInt8((byte) PayloadMessagePackType.PartyFinder); + writer.WriteUInt8((byte)PayloadMessagePackType.PartyFinder); writer.WriteUInt32(partyFinderPayload.Id); break; case UriPayload uriPayload: - writer.WriteUInt8((byte) PayloadMessagePackType.Uri); + writer.WriteUInt8((byte)PayloadMessagePackType.Uri); writer.WriteString(Encoding.UTF8.GetBytes(uriPayload.Uri.ToString())); break; default: - writer.WriteUInt8((byte) PayloadMessagePackType.Other); + writer.WriteUInt8((byte)PayloadMessagePackType.Other); writer.Write(value.Encode()); break; } } - public Payload? Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) { + public Payload? Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) + { if (reader.TryReadNil()) return null; if (reader.ReadArrayHeader() != 2) throw new InvalidOperationException("Invalid array count for Payload object"); - var type = (PayloadMessagePackType) reader.ReadByte(); - switch (type) { - case PayloadMessagePackType.Achievement: - return new AchievementPayload(reader.ReadUInt32()); - case PayloadMessagePackType.PartyFinder: - return new PartyFinderPayload(reader.ReadUInt32()); - case PayloadMessagePackType.Uri: - return new UriPayload(new Uri(reader.ReadString() ?? "")); - case PayloadMessagePackType.Other: - default: - var bytes = reader.ReadBytes() ?? new ReadOnlySequence(); - var binReader = new BinaryReader(new MemoryStream(bytes.ToArray())); - return Payload.Decode(binReader); + var type = (PayloadMessagePackType)reader.ReadByte(); + switch (type) + { + case PayloadMessagePackType.Achievement: + return new AchievementPayload(reader.ReadUInt32()); + case PayloadMessagePackType.PartyFinder: + return new PartyFinderPayload(reader.ReadUInt32()); + case PayloadMessagePackType.Uri: + return new UriPayload(new Uri(reader.ReadString() ?? "")); + case PayloadMessagePackType.Other: + default: + var bytes = reader.ReadBytes() ?? new ReadOnlySequence(); + var binReader = new BinaryReader(new MemoryStream(bytes.ToArray())); + return Payload.Decode(binReader); } } } -public class SeStringMessagePackFormatter : IMessagePackFormatter { - public void Serialize(ref MessagePackWriter writer, SeString value, MessagePackSerializerOptions options) { +public class SeStringMessagePackFormatter : IMessagePackFormatter +{ + public void Serialize(ref MessagePackWriter writer, SeString value, MessagePackSerializerOptions options) + { options.Resolver.GetFormatter>()!.Serialize(ref writer, value.Payloads, options); } - public SeString Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) { + public SeString Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) + { return new SeString(options.Resolver.GetFormatter>()!.Deserialize(ref reader, options)); } } -internal class MessageStore : IDisposable { - internal const int MessageQueryLimit = 10_000; +internal class MessageStore : IDisposable +{ + private const int MessageQueryLimit = 10_000; private string DbPath { get; } @@ -99,19 +112,20 @@ internal class MessageStore : IDisposable { internal static readonly MessagePackSerializerOptions MsgPackOptions = MessagePackSerializerOptions.Standard .WithResolver(CompositeResolver.Create( - new IMessagePackFormatter[] { - new PayloadMessagePackFormatter(), - new SeStringMessagePackFormatter(), - }, - new IFormatterResolver[] { StandardResolver.Instance })); + new IMessagePackFormatter[] { new PayloadMessagePackFormatter(), new SeStringMessagePackFormatter(), }, + new IFormatterResolver[] { StandardResolver.Instance } + ) + ); - internal MessageStore(string dbPath) { + internal MessageStore(string dbPath) + { DbPath = dbPath; Connection = Connect(); Migrate(); } - public void Dispose() { + public void Dispose() + { Connection.Close(); Connection.Dispose(); // Closing the connection doesn't immediately release the file. @@ -119,13 +133,16 @@ internal class MessageStore : IDisposable { GC.WaitForPendingFinalizers(); } - private SqliteConnection Connect() { - var uriBuilder = new SqliteConnectionStringBuilder { + private SqliteConnection Connect() + { + var uriBuilder = new SqliteConnectionStringBuilder + { DataSource = DbPath, DefaultTimeout = 5, Pooling = false, Mode = SqliteOpenMode.ReadWriteCreate, }; + var conn = new SqliteConnection(uriBuilder.ToString()); conn.Open(); conn.Execute(@"PRAGMA journal_mode=WAL;"); @@ -135,7 +152,8 @@ internal class MessageStore : IDisposable { return conn; } - private void Migrate() { + private void Migrate() + { // TODO: this should be improved/swapped out for a library at some // point. Connection.Execute(@" @@ -158,18 +176,21 @@ internal class MessageStore : IDisposable { "); } - internal void Reconnect() { + internal void Reconnect() + { Connection.Close(); Connection.Dispose(); Connection = Connect(); } - internal void ClearMessages() { + internal void ClearMessages() + { Connection.Execute("DELETE FROM messages;"); PerformMaintenance(); } - internal void PerformMaintenance() { + internal void PerformMaintenance() + { Connection.Execute(@" VACUUM; REINDEX messages; @@ -177,15 +198,9 @@ internal class MessageStore : IDisposable { "); } - internal long DatabaseSize() { - return !File.Exists(DbPath) ? 0 : new FileInfo(DbPath).Length; - } - private string LogPath => DbPath + "-wal"; - - internal long DatabaseLogSize() { - return !File.Exists(LogPath) ? 0 : new FileInfo(LogPath).Length; - } + internal long DatabaseSize() => !File.Exists(DbPath) ? 0 : new FileInfo(DbPath).Length; + internal long DatabaseLogSize() => !File.Exists(LogPath) ? 0 : new FileInfo(LogPath).Length; internal int MessageCount() { @@ -194,7 +209,8 @@ internal class MessageStore : IDisposable { return Convert.ToInt32(cmd.ExecuteScalar()); } - internal void UpsertMessage(Message message) { + internal void UpsertMessage(Message message) + { var cmd = Connection.CreateCommand(); cmd.CommandText = @" INSERT INTO messages ( @@ -256,7 +272,8 @@ internal class MessageStore : IDisposable { /// The receiver content ID to filter by. If null, no filtering is performed. /// Only show messages since this date. If null, no filtering is performed. /// The amount to return. Defaults to 10,000. - internal MessageEnumerator GetMostRecentMessages(ulong? receiver = null, DateTimeOffset? since = null, int count = MessageQueryLimit) { + internal MessageEnumerator GetMostRecentMessages(ulong? receiver = null, DateTimeOffset? since = null, int count = MessageQueryLimit) + { var whereClauses = new List(); if (receiver != null) whereClauses.Add("Receiver = $Receiver"); @@ -303,17 +320,21 @@ internal class MessageStore : IDisposable { } } -internal class MessageEnumerator(DbDataReader reader) : IEnumerable { +internal class MessageEnumerator(DbDataReader reader) : IEnumerable +{ private const int MaxErrorLogs = 10; private int _errorCount; public bool DidError => _errorCount > 0; - public IEnumerator GetEnumerator() { - while (reader.Read()) { + public IEnumerator GetEnumerator() + { + while (reader.Read()) + { var id = Guid.Empty; Message msg; - try { + try + { id = reader.GetGuid(0); msg = new Message( id, @@ -321,36 +342,35 @@ internal class MessageEnumerator(DbDataReader reader) : IEnumerable { (ulong)reader.GetInt64(2), DateTimeOffset.FromUnixTimeMilliseconds(reader.GetInt64(3)), new ChatCode((ushort)reader.GetInt32(4)), - MessagePackSerializer.Deserialize>(reader.GetFieldValue(5), - MessageStore.MsgPackOptions), - MessagePackSerializer.Deserialize>(reader.GetFieldValue(6), - MessageStore.MsgPackOptions), - MessagePackSerializer.Deserialize(reader.GetFieldValue(7), - MessageStore.MsgPackOptions), - MessagePackSerializer.Deserialize(reader.GetFieldValue(8), - MessageStore.MsgPackOptions), + MessagePackSerializer.Deserialize>(reader.GetFieldValue(5), MessageStore.MsgPackOptions), + MessagePackSerializer.Deserialize>(reader.GetFieldValue(6), MessageStore.MsgPackOptions), + MessagePackSerializer.Deserialize(reader.GetFieldValue(7), MessageStore.MsgPackOptions), + MessagePackSerializer.Deserialize(reader.GetFieldValue(8), MessageStore.MsgPackOptions), new SortCode((uint)reader.GetInt32(9)), reader.GetGuid(10) ); - } catch (Exception e) { + } + catch (Exception e) + { if (_errorCount < MaxErrorLogs) Plugin.Log.Error($"Exception while reading message '{id}' from database: {e}"); _errorCount++; if (_errorCount == MaxErrorLogs) Plugin.Log.Error("Further parsing errors will not be logged"); -#if DEBUG + #if DEBUG throw; -#else + #else continue; -#endif + #endif } yield return msg; } } - IEnumerator IEnumerable.GetEnumerator() { + IEnumerator IEnumerable.GetEnumerator() + { return GetEnumerator(); } } diff --git a/ChatTwo/Resources/Language.Designer.cs b/ChatTwo/Resources/Language.Designer.cs index 22c1b21..fd57c1c 100755 --- a/ChatTwo/Resources/Language.Designer.cs +++ b/ChatTwo/Resources/Language.Designer.cs @@ -1761,7 +1761,7 @@ namespace ChatTwo.Resources { } /// - /// Looks up a localized string similar to Stored messages: {0:N0}/{1:N0}. + /// Looks up a localized string similar to Stored messages: {0:N0}. /// internal static string Options_Database_Metadata_MessageCount { get { diff --git a/ChatTwo/Resources/Language.resx b/ChatTwo/Resources/Language.resx index e53f337..05bf77d 100644 --- a/ChatTwo/Resources/Language.resx +++ b/ChatTwo/Resources/Language.resx @@ -965,7 +965,7 @@ Log size: {0} - Stored messages: {0:N0}/{1:N0} + Stored messages: {0:N0} Path: {0} diff --git a/ChatTwo/Ui/SettingsTabs/Database.cs b/ChatTwo/Ui/SettingsTabs/Database.cs index 0f5e7ed..2e75604 100755 --- a/ChatTwo/Ui/SettingsTabs/Database.cs +++ b/ChatTwo/Ui/SettingsTabs/Database.cs @@ -117,7 +117,7 @@ internal sealed class Database : ISettingsTab if (ImGui.IsItemHovered()) ImGui.SetTooltip(DatabaseLogSize.ToString("N0") + "B"); - ImGuiUtil.HelpText(string.Format(Language.Options_Database_Metadata_MessageCount, DatabaseMessageCount, MessageStore.MessageQueryLimit)); + ImGuiUtil.HelpText(string.Format(Language.Options_Database_Metadata_MessageCount, DatabaseMessageCount)); if (ImGuiUtil.CtrlShiftButton(Language.Options_ClearDatabase_Button, Language.Options_ClearDatabase_Tooltip)) {