From 0c37bfa13c6fd870190c4dd22f3027b25acc5db1 Mon Sep 17 00:00:00 2001 From: kjh2064 Date: Sun, 12 Jul 2026 22:25:38 +0900 Subject: [PATCH] fix(qe-m2-03): parse supported Npgsql keys only and ignore custom options gracefully --- .../HistoryIngestionPgTests.cs | 35 ++++++++++++++----- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/dotnet/QuantEngine.Core.Tests/HistoryIngestionPgTests.cs b/src/dotnet/QuantEngine.Core.Tests/HistoryIngestionPgTests.cs index a0c40809..0e596a06 100644 --- a/src/dotnet/QuantEngine.Core.Tests/HistoryIngestionPgTests.cs +++ b/src/dotnet/QuantEngine.Core.Tests/HistoryIngestionPgTests.cs @@ -53,15 +53,32 @@ namespace QuantEngine.Core.Tests string connStr = rawDsn; if (rawDsn.Contains("host=") || rawDsn.Contains("dbname=")) { - connStr = rawDsn - .Replace("options='-c search_path=quantengine'", "") - .Replace("options=\"-c search_path=quantengine\"", "") - .Replace("dbname=", "Database=") - .Replace("user=", "Username=") - .Replace("host=", "Host=") - .Replace("port=", "Port=") - .Trim(); - connStr = string.Join(";", connStr.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)) + ";Search Path=quantengine"; + try + { + var builder = new NpgsqlConnectionStringBuilder(); + var parts = rawDsn.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); + foreach (var p in parts) + { + var kv = p.Split('=', 2); + if (kv.Length == 2) + { + string key = kv[0].Trim().ToLowerInvariant(); + string val = kv[1].Trim().Trim('\'').Trim('"'); + if (key == "host") builder.Host = val; + else if (key == "port" && int.TryParse(val, out var pi)) builder.Port = pi; + else if (key == "dbname") builder.Database = val; + else if (key == "user") builder.Username = val; + else if (key == "password") builder.Password = val; + } + } + builder.SearchPath = "quantengine"; + connStr = builder.ConnectionString; + } + catch + { + // Fallback to rawDsn if builder logic fails + connStr = rawDsn; + } } try