refactor(messagestore): inject IPluginLogProxy for test isolation
MessageStore's Migrate0 (and the Migrate1/2/3 siblings) called Plugin.Log.Information directly, which prevented an isolated xUnit construction test from running — Dalamud.dll cannot load in the test AppDomain. With IPluginLogProxy threaded through the ctor and the inner MessageEnumerator, the whole MessageStore.cs file is now Dalamud-static free and the Build-Suite covers it (Floor 688 -> 690). This is the second half of F12.2; the remaining ~82 Plugin.Log call sites in the rest of the plugin will be routed through the static Plugin.LogProxy wrapper in a follow-up commit.
This commit is contained in:
@@ -52,7 +52,7 @@ internal class MessageManager : IAsyncDisposable
|
||||
{
|
||||
Plugin = plugin;
|
||||
|
||||
Store = new MessageStore(DatabasePath(), Plugin.PlatformUtil);
|
||||
Store = new MessageStore(DatabasePath(), Plugin.PlatformUtil, Plugin.LogProxy);
|
||||
|
||||
PendingMessageThread = new Thread(() =>
|
||||
ProcessPendingMessages(PendingThreadCancellationToken.Token)
|
||||
|
||||
+19
-18
@@ -137,11 +137,13 @@ internal class MessageStore : IDisposable
|
||||
);
|
||||
|
||||
private readonly IPlatformUtil _platformUtil;
|
||||
private readonly IPluginLogProxy _logger;
|
||||
|
||||
internal MessageStore(string dbPath, IPlatformUtil platformUtil)
|
||||
internal MessageStore(string dbPath, IPlatformUtil platformUtil, IPluginLogProxy logger)
|
||||
{
|
||||
DbPath = dbPath;
|
||||
_platformUtil = platformUtil;
|
||||
_logger = logger;
|
||||
Connection = Connect();
|
||||
Migrate();
|
||||
}
|
||||
@@ -204,7 +206,7 @@ internal class MessageStore : IDisposable
|
||||
|
||||
private void Migrate0()
|
||||
{
|
||||
Plugin.Log.Information("Running migration 0: Creating tables");
|
||||
_logger.Information("Running migration 0: Creating tables");
|
||||
Connection.Execute(
|
||||
@"
|
||||
CREATE TABLE IF NOT EXISTS messages (
|
||||
@@ -231,7 +233,7 @@ internal class MessageStore : IDisposable
|
||||
|
||||
private void Migrate1()
|
||||
{
|
||||
Plugin.Log.Information("Running migration 1: Adding Deleted column");
|
||||
_logger.Information("Running migration 1: Adding Deleted column");
|
||||
Connection.Execute(
|
||||
@"
|
||||
ALTER TABLE messages ADD COLUMN Deleted BOOLEAN NOT NULL DEFAULT false;
|
||||
@@ -243,7 +245,7 @@ internal class MessageStore : IDisposable
|
||||
|
||||
private void Migrate2()
|
||||
{
|
||||
Plugin.Log.Information("Running migration 2: Adding Channel generated column");
|
||||
_logger.Information("Running migration 2: Adding Channel generated column");
|
||||
Connection.Execute(
|
||||
@"
|
||||
ALTER TABLE messages ADD COLUMN Channel INTEGER GENERATED ALWAYS AS (Code & 0x7f) VIRTUAL;
|
||||
@@ -271,15 +273,13 @@ internal class MessageStore : IDisposable
|
||||
|
||||
private void Migrate3()
|
||||
{
|
||||
Plugin.Log.Information("Running migration 3: Fix log kinds to fit the new format");
|
||||
_logger.Information("Running migration 3: Fix log kinds to fit the new format");
|
||||
|
||||
// Recovery for partially-applied Migrate3: schema already in target
|
||||
// shape but user_version was never bumped -- just record and exit.
|
||||
if (ColumnExists("messages", "ChatType") && !ColumnExists("messages", "Code"))
|
||||
{
|
||||
Plugin.Log.Information(
|
||||
"Migration 3: schema already migrated, only bumping user_version"
|
||||
);
|
||||
_logger.Information("Migration 3: schema already migrated, only bumping user_version");
|
||||
SetMigrationVersion(3);
|
||||
return;
|
||||
}
|
||||
@@ -309,7 +309,7 @@ internal class MessageStore : IDisposable
|
||||
|
||||
private void SetMigrationVersion(int version)
|
||||
{
|
||||
Plugin.Log.Information($"Setting version {version}");
|
||||
_logger.Information($"Setting version {version}");
|
||||
using var cmd = Connection.CreateCommand();
|
||||
// PRAGMA does not accept SQLite parameter bindings; version is a
|
||||
// compile-time int from the migration sequence, never user input.
|
||||
@@ -461,7 +461,7 @@ internal class MessageStore : IDisposable
|
||||
// Privacy filter -- drop disallowed ChatTypes before they reach storage.
|
||||
if (!Plugin.Config.IsAllowedForStorage(message.Code.Type))
|
||||
{
|
||||
Plugin.Log.Verbose($"Privacy filter dropped message: ChatType={message.Code.Type}");
|
||||
_logger.Verbose($"Privacy filter dropped message: ChatType={message.Code.Type}");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -554,7 +554,7 @@ internal class MessageStore : IDisposable
|
||||
if (to is not null)
|
||||
cmd.Parameters.AddWithValue("$To", to.Value.ToUnixTimeMilliseconds());
|
||||
|
||||
return new MessageEnumerator(cmd.ExecuteReader());
|
||||
return new MessageEnumerator(cmd.ExecuteReader(), _logger);
|
||||
}
|
||||
|
||||
// Returns the most recent messages, oldest-first.
|
||||
@@ -602,7 +602,7 @@ internal class MessageStore : IDisposable
|
||||
|
||||
cmd.Parameters.AddWithValue("$Count", count);
|
||||
|
||||
return new MessageEnumerator(cmd.ExecuteReader());
|
||||
return new MessageEnumerator(cmd.ExecuteReader(), _logger);
|
||||
}
|
||||
|
||||
// Returns up to limit tells exchanged with the named player, oldest-first.
|
||||
@@ -640,7 +640,7 @@ internal class MessageStore : IDisposable
|
||||
cmd.Parameters.AddWithValue("$ScanLimit", sqlScanLimit);
|
||||
|
||||
var collected = new List<Message>();
|
||||
using var enumerator = new MessageEnumerator(cmd.ExecuteReader());
|
||||
using var enumerator = new MessageEnumerator(cmd.ExecuteReader(), _logger);
|
||||
foreach (var message in enumerator)
|
||||
{
|
||||
if (!ChunkUtil.MatchesSender(message, senderName, senderWorld))
|
||||
@@ -732,7 +732,7 @@ internal class MessageStore : IDisposable
|
||||
cmd.Parameters.AddWithValue("$After", ((DateTimeOffset)after).ToUnixTimeMilliseconds());
|
||||
cmd.Parameters.AddWithValue("$Before", ((DateTimeOffset)before).ToUnixTimeMilliseconds());
|
||||
|
||||
return new MessageEnumerator(cmd.ExecuteReader());
|
||||
return new MessageEnumerator(cmd.ExecuteReader(), _logger);
|
||||
}
|
||||
|
||||
internal MessageEnumerator GetPagedDateRange(
|
||||
@@ -776,7 +776,7 @@ internal class MessageStore : IDisposable
|
||||
cmd.Parameters.AddWithValue("$Offset", DbViewer.RowPerPage * page);
|
||||
cmd.Parameters.AddWithValue("$OffsetCount", DbViewer.RowPerPage);
|
||||
|
||||
return new MessageEnumerator(cmd.ExecuteReader());
|
||||
return new MessageEnumerator(cmd.ExecuteReader(), _logger);
|
||||
}
|
||||
|
||||
// Builds a "$prefix0,$prefix1,..." placeholder list and binds values to the command.
|
||||
@@ -796,13 +796,14 @@ internal class MessageStore : IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
internal class MessageEnumerator(DbDataReader reader)
|
||||
internal class MessageEnumerator(DbDataReader reader, IPluginLogProxy logger)
|
||||
: IEnumerable<Message>,
|
||||
IDisposable,
|
||||
IAsyncDisposable
|
||||
{
|
||||
private const int MaxErrorLogs = 10;
|
||||
|
||||
private readonly IPluginLogProxy _logger = logger;
|
||||
private readonly List<Guid> FailedIds = [];
|
||||
private int FailedCount;
|
||||
public bool DidError => FailedCount > 0;
|
||||
@@ -848,10 +849,10 @@ internal class MessageEnumerator(DbDataReader reader)
|
||||
catch (Exception e)
|
||||
{
|
||||
if (FailedCount < MaxErrorLogs)
|
||||
Plugin.Log.Error($"Exception while reading message '{id}' from database: {e}");
|
||||
_logger.Error($"Exception while reading message '{id}' from database: {e}");
|
||||
FailedCount++;
|
||||
if (FailedCount == MaxErrorLogs)
|
||||
Plugin.Log.Error("Further parsing errors will not be logged");
|
||||
_logger.Error("Further parsing errors will not be logged");
|
||||
if (id != Guid.Empty)
|
||||
FailedIds.Add(id);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user