using System.Collections.ObjectModel; using Npgsql; namespace pgLabII.PgUtils.ConnectionStrings; public ref struct PqConnectionStringParser { // Note possible keywords // host //hostaddr //port //dbname //user //password //passfile //channel_binding //connect_timeout //client_encoding //options //application_name //fallback_application_name //keepalives //keepalives_idle //keepalives_interval //keepalives_count //tcp_user_timeout //replication //gssencmode //sslmode //requiresll //sslcompression //sslcert //sslkey //sslpassword //sslrootcert //sslcrl //sslcrldir //sslsni //requirepeer //ssl_min_protocol_version //ssl_max_protocol_version //krbsrvname //gsslib //service //target_session_attrs public static IDictionary Parse(string input) { return new PqConnectionStringParser( new PqConnectionStringTokenizer(input) ).Parse(); } private readonly IPqConnectionStringTokenizer tokenizer; private readonly Dictionary result = new(); public PqConnectionStringParser(IPqConnectionStringTokenizer tokenizer) { this.tokenizer = tokenizer; } public IDictionary Parse() { result.Clear(); while (!tokenizer.Eof) ParsePair(); return result; } private void ParsePair() { string kw = tokenizer.GetKeyword(); tokenizer.ConsumeEquals(); string v = tokenizer.GetValue(); result.Add(kw, v); //switch (kw) //{ // case "host": // case "hostaddr": // result.Host = v.ToString(); // break; // case "port": // result.Port = int.Parse(v); // break; // case "dbname": // result.Database = v.ToString(); // break; // case "user": // result.Username = v.ToString(); // break; // case "password": // result.Password = v.ToString(); // break; // case "connect_timeout": // result.Timeout = int.Parse(v); // break; // case "application_name": // result.ApplicationName = v.ToString(); // break; // case "options": // result.Options = v.ToString(); // break; // case "sslmode": // result.SslMode = ToSslMode(v); // break; // default: // // Todo what do we do with values we do not support/recognize? // break; //} } private SslMode ToSslMode(ReadOnlySpan v) => v switch { "disable" => SslMode.Disable, "allow" => SslMode.Allow, "prefer" => SslMode.Prefer, "require" => SslMode.Require, "verify-ca" => SslMode.VerifyCA, "verify-full" => SslMode.VerifyFull, _ => throw new ArgumentException("Not a valid SSL mode"), }; }