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;
|
Plugin = plugin;
|
||||||
|
|
||||||
Store = new MessageStore(DatabasePath(), Plugin.PlatformUtil);
|
Store = new MessageStore(DatabasePath(), Plugin.PlatformUtil, Plugin.LogProxy);
|
||||||
|
|
||||||
PendingMessageThread = new Thread(() =>
|
PendingMessageThread = new Thread(() =>
|
||||||
ProcessPendingMessages(PendingThreadCancellationToken.Token)
|
ProcessPendingMessages(PendingThreadCancellationToken.Token)
|
||||||
|
|||||||
+19
-18
@@ -137,11 +137,13 @@ internal class MessageStore : IDisposable
|
|||||||
);
|
);
|
||||||
|
|
||||||
private readonly IPlatformUtil _platformUtil;
|
private readonly IPlatformUtil _platformUtil;
|
||||||
|
private readonly IPluginLogProxy _logger;
|
||||||
|
|
||||||
internal MessageStore(string dbPath, IPlatformUtil platformUtil)
|
internal MessageStore(string dbPath, IPlatformUtil platformUtil, IPluginLogProxy logger)
|
||||||
{
|
{
|
||||||
DbPath = dbPath;
|
DbPath = dbPath;
|
||||||
_platformUtil = platformUtil;
|
_platformUtil = platformUtil;
|
||||||
|
_logger = logger;
|
||||||
Connection = Connect();
|
Connection = Connect();
|
||||||
Migrate();
|
Migrate();
|
||||||
}
|
}
|
||||||
@@ -204,7 +206,7 @@ internal class MessageStore : IDisposable
|
|||||||
|
|
||||||
private void Migrate0()
|
private void Migrate0()
|
||||||
{
|
{
|
||||||
Plugin.Log.Information("Running migration 0: Creating tables");
|
_logger.Information("Running migration 0: Creating tables");
|
||||||
Connection.Execute(
|
Connection.Execute(
|
||||||
@"
|
@"
|
||||||
CREATE TABLE IF NOT EXISTS messages (
|
CREATE TABLE IF NOT EXISTS messages (
|
||||||
@@ -231,7 +233,7 @@ internal class MessageStore : IDisposable
|
|||||||
|
|
||||||
private void Migrate1()
|
private void Migrate1()
|
||||||
{
|
{
|
||||||
Plugin.Log.Information("Running migration 1: Adding Deleted column");
|
_logger.Information("Running migration 1: Adding Deleted column");
|
||||||
Connection.Execute(
|
Connection.Execute(
|
||||||
@"
|
@"
|
||||||
ALTER TABLE messages ADD COLUMN Deleted BOOLEAN NOT NULL DEFAULT false;
|
ALTER TABLE messages ADD COLUMN Deleted BOOLEAN NOT NULL DEFAULT false;
|
||||||
@@ -243,7 +245,7 @@ internal class MessageStore : IDisposable
|
|||||||
|
|
||||||
private void Migrate2()
|
private void Migrate2()
|
||||||
{
|
{
|
||||||
Plugin.Log.Information("Running migration 2: Adding Channel generated column");
|
_logger.Information("Running migration 2: Adding Channel generated column");
|
||||||
Connection.Execute(
|
Connection.Execute(
|
||||||
@"
|
@"
|
||||||
ALTER TABLE messages ADD COLUMN Channel INTEGER GENERATED ALWAYS AS (Code & 0x7f) VIRTUAL;
|
ALTER TABLE messages ADD COLUMN Channel INTEGER GENERATED ALWAYS AS (Code & 0x7f) VIRTUAL;
|
||||||
@@ -271,15 +273,13 @@ internal class MessageStore : IDisposable
|
|||||||
|
|
||||||
private void Migrate3()
|
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
|
// Recovery for partially-applied Migrate3: schema already in target
|
||||||
// shape but user_version was never bumped -- just record and exit.
|
// shape but user_version was never bumped -- just record and exit.
|
||||||
if (ColumnExists("messages", "ChatType") && !ColumnExists("messages", "Code"))
|
if (ColumnExists("messages", "ChatType") && !ColumnExists("messages", "Code"))
|
||||||
{
|
{
|
||||||
Plugin.Log.Information(
|
_logger.Information("Migration 3: schema already migrated, only bumping user_version");
|
||||||
"Migration 3: schema already migrated, only bumping user_version"
|
|
||||||
);
|
|
||||||
SetMigrationVersion(3);
|
SetMigrationVersion(3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -309,7 +309,7 @@ internal class MessageStore : IDisposable
|
|||||||
|
|
||||||
private void SetMigrationVersion(int version)
|
private void SetMigrationVersion(int version)
|
||||||
{
|
{
|
||||||
Plugin.Log.Information($"Setting version {version}");
|
_logger.Information($"Setting version {version}");
|
||||||
using var cmd = Connection.CreateCommand();
|
using var cmd = Connection.CreateCommand();
|
||||||
// PRAGMA does not accept SQLite parameter bindings; version is a
|
// PRAGMA does not accept SQLite parameter bindings; version is a
|
||||||
// compile-time int from the migration sequence, never user input.
|
// 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.
|
// Privacy filter -- drop disallowed ChatTypes before they reach storage.
|
||||||
if (!Plugin.Config.IsAllowedForStorage(message.Code.Type))
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -554,7 +554,7 @@ internal class MessageStore : IDisposable
|
|||||||
if (to is not null)
|
if (to is not null)
|
||||||
cmd.Parameters.AddWithValue("$To", to.Value.ToUnixTimeMilliseconds());
|
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.
|
// Returns the most recent messages, oldest-first.
|
||||||
@@ -602,7 +602,7 @@ internal class MessageStore : IDisposable
|
|||||||
|
|
||||||
cmd.Parameters.AddWithValue("$Count", count);
|
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.
|
// 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);
|
cmd.Parameters.AddWithValue("$ScanLimit", sqlScanLimit);
|
||||||
|
|
||||||
var collected = new List<Message>();
|
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)
|
foreach (var message in enumerator)
|
||||||
{
|
{
|
||||||
if (!ChunkUtil.MatchesSender(message, senderName, senderWorld))
|
if (!ChunkUtil.MatchesSender(message, senderName, senderWorld))
|
||||||
@@ -732,7 +732,7 @@ internal class MessageStore : IDisposable
|
|||||||
cmd.Parameters.AddWithValue("$After", ((DateTimeOffset)after).ToUnixTimeMilliseconds());
|
cmd.Parameters.AddWithValue("$After", ((DateTimeOffset)after).ToUnixTimeMilliseconds());
|
||||||
cmd.Parameters.AddWithValue("$Before", ((DateTimeOffset)before).ToUnixTimeMilliseconds());
|
cmd.Parameters.AddWithValue("$Before", ((DateTimeOffset)before).ToUnixTimeMilliseconds());
|
||||||
|
|
||||||
return new MessageEnumerator(cmd.ExecuteReader());
|
return new MessageEnumerator(cmd.ExecuteReader(), _logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal MessageEnumerator GetPagedDateRange(
|
internal MessageEnumerator GetPagedDateRange(
|
||||||
@@ -776,7 +776,7 @@ internal class MessageStore : IDisposable
|
|||||||
cmd.Parameters.AddWithValue("$Offset", DbViewer.RowPerPage * page);
|
cmd.Parameters.AddWithValue("$Offset", DbViewer.RowPerPage * page);
|
||||||
cmd.Parameters.AddWithValue("$OffsetCount", DbViewer.RowPerPage);
|
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.
|
// 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>,
|
: IEnumerable<Message>,
|
||||||
IDisposable,
|
IDisposable,
|
||||||
IAsyncDisposable
|
IAsyncDisposable
|
||||||
{
|
{
|
||||||
private const int MaxErrorLogs = 10;
|
private const int MaxErrorLogs = 10;
|
||||||
|
|
||||||
|
private readonly IPluginLogProxy _logger = logger;
|
||||||
private readonly List<Guid> FailedIds = [];
|
private readonly List<Guid> FailedIds = [];
|
||||||
private int FailedCount;
|
private int FailedCount;
|
||||||
public bool DidError => FailedCount > 0;
|
public bool DidError => FailedCount > 0;
|
||||||
@@ -848,10 +849,10 @@ internal class MessageEnumerator(DbDataReader reader)
|
|||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
if (FailedCount < MaxErrorLogs)
|
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++;
|
FailedCount++;
|
||||||
if (FailedCount == MaxErrorLogs)
|
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)
|
if (id != Guid.Empty)
|
||||||
FailedIds.Add(id);
|
FailedIds.Add(id);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user