fix query formatting on export option

This commit is contained in:
2026-05-20 11:39:35 +02:00
parent 6f285d6bd0
commit 47b57b5d3c
3 changed files with 38 additions and 40 deletions
Binary file not shown.
+21 -23
View File
@@ -13,28 +13,19 @@ public sealed class HdbCliRunner
/// </summary> /// </summary>
public static List<HdbUserstoreKey> ListKeys() public static List<HdbUserstoreKey> ListKeys()
{ {
var result = RunAndCapture(HdbClientLocator.HdbUserstore, "list"); var result = RunAndCapture(HdbClientLocator.HdbUserstore, ["list"]);
if (!result.Success) if (!result.Success)
return []; return [];
return HdbUserstoreKey.ParseFrom(result.Output); return HdbUserstoreKey.ParseFrom(result.Output);
} }
/// <summary>
/// Tests a key connection by running a trivial SELECT against DUMMY.
/// Returns true on success.
/// </summary>
public static bool TestKey(string key) public static bool TestKey(string key)
{ {
var result = RunAndCapture( var result = RunAndCapture(HdbClientLocator.HdbSql,
HdbClientLocator.HdbSql, ["-U", key, "SELECT 'ok' FROM DUMMY"]);
$"-U \"{key}\" \"SELECT 'ok' FROM DUMMY\"");
return result.Success && result.Output.Contains("ok"); return result.Success && result.Output.Contains("ok");
} }
/// <summary>
/// Lists eligible schemas for the given userstore key.
/// </summary>
public static (bool Success, List<string> Schemas, string Error) ListSchemas(string key) public static (bool Success, List<string> Schemas, string Error) ListSchemas(string key)
{ {
const string query = const string query =
@@ -42,7 +33,7 @@ public sealed class HdbCliRunner
"WHERE SCHEMA_OWNER = 'SYSTEM' " + "WHERE SCHEMA_OWNER = 'SYSTEM' " +
"AND SCHEMA_NAME NOT IN ('_SYS_SECURITY', 'IFSERV', 'B1if', 'SYSTEM', 'RSP');"; "AND SCHEMA_NAME NOT IN ('_SYS_SECURITY', 'IFSERV', 'B1if', 'SYSTEM', 'RSP');";
var result = RunAndCapture(HdbClientLocator.HdbSql, $"-U \"{key}\" \"{query}\""); var result = RunAndCapture(HdbClientLocator.HdbSql, ["-U", key, query]);
if (!result.Success) if (!result.Success)
return (false, [], result.Output); return (false, [], result.Output);
@@ -73,9 +64,11 @@ public sealed class HdbCliRunner
Action<string> onOutputLine, Action<string> onOutputLine,
CancellationToken ct) CancellationToken ct)
{ {
// Use ArgumentList (not Arguments) so args are passed directly to the process
// without shell quoting — double quotes inside SQL won't break the argument boundary.
return await RunStreamingAsync( return await RunStreamingAsync(
HdbClientLocator.HdbSql, HdbClientLocator.HdbSql,
$"-U \"{key}\" \"{sql}\"", ["-U", key, sql],
onOutputLine, onOutputLine,
ct); ct);
} }
@@ -90,23 +83,29 @@ public sealed class HdbCliRunner
Action<string> onOutputLine, Action<string> onOutputLine,
CancellationToken ct) CancellationToken ct)
{ {
return await RunStreamingAsync(executable, arguments, onOutputLine, ct); // Shell commands (tar, pigz) need shell parsing for things like -I "pigz -p N",
// so we use a bash -c wrapper to ensure correct tokenisation.
return await RunStreamingAsync(
"/bin/bash",
["-c", arguments],
onOutputLine,
ct);
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
private static (bool Success, string Output) RunAndCapture(string exe, string args) private static (bool Success, string Output) RunAndCapture(string exe, string[] args)
{ {
try try
{ {
var psi = new ProcessStartInfo(exe) var psi = new ProcessStartInfo(exe)
{ {
Arguments = args,
RedirectStandardOutput = true, RedirectStandardOutput = true,
RedirectStandardError = true, RedirectStandardError = true,
UseShellExecute = false, UseShellExecute = false,
CreateNoWindow = true, CreateNoWindow = true,
}; };
foreach (var a in args) psi.ArgumentList.Add(a);
using var proc = Process.Start(psi); using var proc = Process.Start(psi);
if (proc is null) if (proc is null)
@@ -116,10 +115,9 @@ public sealed class HdbCliRunner
var stderr = proc.StandardError.ReadToEnd(); var stderr = proc.StandardError.ReadToEnd();
proc.WaitForExit(); proc.WaitForExit();
if (proc.ExitCode == 0) return proc.ExitCode == 0
return (true, stdout); ? (true, stdout)
else : (false, string.IsNullOrWhiteSpace(stderr) ? stdout : stderr);
return (false, string.IsNullOrWhiteSpace(stderr) ? stdout : stderr);
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -129,18 +127,18 @@ public sealed class HdbCliRunner
private static async Task<int> RunStreamingAsync( private static async Task<int> RunStreamingAsync(
string exe, string exe,
string args, string[] args,
Action<string> onOutputLine, Action<string> onOutputLine,
CancellationToken ct) CancellationToken ct)
{ {
var psi = new ProcessStartInfo(exe) var psi = new ProcessStartInfo(exe)
{ {
Arguments = args,
RedirectStandardOutput = true, RedirectStandardOutput = true,
RedirectStandardError = true, RedirectStandardError = true,
UseShellExecute = false, UseShellExecute = false,
CreateNoWindow = true, CreateNoWindow = true,
}; };
foreach (var a in args) psi.ArgumentList.Add(a);
Process? proc; Process? proc;
try try
+3 -3
View File
@@ -357,7 +357,7 @@ public sealed class SchemaService(string userKey)
private async Task<string> GetTenantNameAsync() private async Task<string> GetTenantNameAsync()
{ {
var sql = SqlQueryBuilder.GetTenantName(); var sql = SqlQueryBuilder.GetTenantName();
var (success, output) = RunCapture(HdbClientLocator.HdbSql, $"-U \"{_key}\" \"{sql}\""); var (success, output) = RunCapture(HdbClientLocator.HdbSql, ["-U", _key, sql]);
if (!success) return ""; if (!success) return "";
foreach (var line in output.Split('\n')) foreach (var line in output.Split('\n'))
@@ -373,18 +373,18 @@ public sealed class SchemaService(string userKey)
return ""; return "";
} }
private static (bool, string) RunCapture(string exe, string args) private static (bool, string) RunCapture(string exe, string[] args)
{ {
try try
{ {
var psi = new SysDiag.ProcessStartInfo(exe) var psi = new SysDiag.ProcessStartInfo(exe)
{ {
Arguments = args,
RedirectStandardOutput = true, RedirectStandardOutput = true,
RedirectStandardError = true, RedirectStandardError = true,
UseShellExecute = false, UseShellExecute = false,
CreateNoWindow = true, CreateNoWindow = true,
}; };
foreach (var a in args) psi.ArgumentList.Add(a);
using var proc = SysDiag.Process.Start(psi); using var proc = SysDiag.Process.Start(psi);
if (proc is null) return (false, ""); if (proc is null) return (false, "");
var stdout = proc.StandardOutput.ReadToEnd(); var stdout = proc.StandardOutput.ReadToEnd();