pgLabII/pgLabII.PgUtils/ConnectionStrings/Pq/PqConnectionStringParser.cs
2025-08-18 19:41:36 +02:00

126 lines
3.2 KiB
C#

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<string, string> Parse(string input)
{
return new PqConnectionStringParser(
new PqConnectionStringTokenizer(input)
).Parse();
}
private readonly IPqConnectionStringTokenizer tokenizer;
private readonly Dictionary<string, string> result = new();
public PqConnectionStringParser(IPqConnectionStringTokenizer tokenizer)
{
this.tokenizer = tokenizer;
}
public IDictionary<string, string> 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<char> 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"),
};
}