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."); } }