using HanaToolbox.Services.Interfaces;
namespace HanaToolbox.Services;
///
/// Locates hdbsql and hdbuserstore binaries using:
/// 1. Value from config (if set)
/// 2. `which` lookup on PATH
/// 3. /usr/sap/hdbclient/
/// 4. /usr/sap/<SID>/HDB<instance>/exe/
///
public sealed class HdbClientLocator(IProcessRunner runner) : IHdbClientLocator
{
public string LocateHdbsql(string? configuredPath, string sid, string instanceNumber) =>
Locate("hdbsql", configuredPath, sid, instanceNumber);
public string LocateHdbuserstore(string? configuredPath, string sid, string instanceNumber) =>
Locate("hdbuserstore", configuredPath, sid, instanceNumber);
private string Locate(string binary, string? configuredPath, string sid, string instanceNumber)
{
// 1. User-configured explicit path
if (!string.IsNullOrWhiteSpace(configuredPath) && File.Exists(configuredPath))
return configuredPath;
// 2. which
var whichResult = runner.RunAsync("/usr/bin/which", [binary]).GetAwaiter().GetResult();
if (whichResult.Success && !string.IsNullOrWhiteSpace(whichResult.StdOut))
return whichResult.StdOut.Split('\n')[0].Trim();
// 3. /usr/sap/hdbclient/
var path3 = $"/usr/sap/hdbclient/{binary}";
if (File.Exists(path3)) return path3;
// 4. /usr/sap//HDB/exe/
var path4 = $"/usr/sap/{sid.ToUpperInvariant()}/HDB{instanceNumber}/exe/{binary}";
if (File.Exists(path4)) return path4;
throw new FileNotFoundException(
$"Could not locate '{binary}'. Set HdbsqlPath/HdbuserstorePath in hanatoolbox.json or ensure it is on PATH.");
}
}