Skip to content

Commit 0a2bd31

Browse files
committed
client-1.4.0 initial
1 parent 44bdb44 commit 0a2bd31

7 files changed

Lines changed: 181 additions & 57 deletions

File tree

NpgsqlRestClient/App.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,7 @@ public static Dictionary<string, int> CreatePostgreSqlErrorCodeToHttpStatusCodeM
197197

198198
public static Action<NpgsqlConnection, Routine, RoutineEndpoint, HttpContext>? BeforeConnectionOpen(string connectionString)
199199
{
200-
var useConnectionApplicationNameWithUsername = GetConfigBool("UseJsonApplicationName", NpgsqlRestCfg);
201-
if (useConnectionApplicationNameWithUsername is false)
200+
if (Config.UseConnectionApplicationNameWithUsername is false)
202201
{
203202
return null;
204203
}

NpgsqlRestClient/Arguments.cs

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
using NpgsqlRest;
44
using NpgsqlRest.HttpFiles;
55
using NpgsqlRest.TsClient;
6-
76
using static NpgsqlRestClient.Config;
87

98
namespace NpgsqlRestClient;
@@ -25,14 +24,18 @@ public static bool Parse(string[] args)
2524
("npgsqlrest [files...]", "Run with the custom configuration files. All configuration files are required."),
2625
("npgsqlrest [file1 -o file2...]", "Use the -o switch to mark the next configuration file as optional. The first file after the -o switch is optional."),
2726
("npgsqlrest [file1 --optional file2...]", "Use --optional switch to mark the next configuration file as optional. The first file after the --optional switch is optional."),
27+
("Note:", "Values in the later file will override the values in the previous one."),
28+
("npgsqlrest [--key=value]", "Override the configuration with this key with a new value (case insensitive, use : to separate sections). "),
2829
(" ", " "),
2930
("npgsqlrest -v, --version", "Show version information."),
3031
("npgsqlrest -h, --help", "Show command line help."),
3132
(" ", " "),
32-
("Note:", "Values in the later file will override the values in the previous one."),
3333
(" ", " "),
34-
("Example:", "npgsqlrest appsettings.json appsettings.Development.json"),
35-
("Example:", "npgsqlrest appsettings.json -o appsettings.Development.json"),
34+
("Examples:", " "),
35+
("Example: use two config files", "npgsqlrest appsettings.json appsettings.Development.json"),
36+
("Example: second config file optional", "npgsqlrest appsettings.json -o appsettings.Development.json"),
37+
("Example: override ApplicationName config", "npgsqlrest --applicationname=Test"),
38+
("Example: override Auth:CookieName config", "npgsqlrest --auth:cookiename=Test"),
3639
]);
3740
}
3841

@@ -53,28 +56,61 @@ public static bool Parse(string[] args)
5356
return false;
5457
}
5558

56-
public static IEnumerable<(string fileName, bool optional)> EnumerateConfigFiles(string[] args)
59+
//public static IEnumerable<(string fileName, bool optional)> EnumerateConfigFiles(string[] args)
60+
//{
61+
// bool nextIsOptional = false;
62+
// foreach(var arg in args)
63+
// {
64+
// if (arg.StartsWith('-'))
65+
// {
66+
// if (arg.ToLowerInvariant() is "-o" or "--optional")
67+
// {
68+
// nextIsOptional = true;
69+
// }
70+
// //else
71+
// //{
72+
// // throw new ArgumentException($"Unknown parameter {arg}");
73+
// //}
74+
// }
75+
// else
76+
// {
77+
// yield return (arg, nextIsOptional);
78+
// nextIsOptional = false;
79+
// }
80+
// }
81+
//}
82+
public static (List<(string fileName, bool optional)> configFiles, string[] commanLineArgs) BuildFromArgs(string[] args)
5783
{
84+
var configFiles = new List<(string fileName, bool optional)>();
85+
var commandLineArgs = new List<string>();
86+
5887
bool nextIsOptional = false;
59-
foreach(var arg in args)
88+
foreach (var arg in args)
6089
{
90+
6191
if (arg.StartsWith('-'))
62-
{
63-
if (arg.ToLowerInvariant() is "-o" or "--optional")
92+
{
93+
var lower = arg.ToLowerInvariant();
94+
if (lower is "-o" or "--optional")
6495
{
6596
nextIsOptional = true;
6697
}
98+
else if (arg.StartsWith("--") && arg.Contains("="))
99+
{
100+
commandLineArgs.Add(arg);
101+
}
67102
else
68103
{
69-
throw new ArgumentException($"Unknown parameter {arg}");
104+
throw new ArgumentException($"Unknown parameter {arg}");
70105
}
71106
}
72107
else
73108
{
74-
yield return (arg, nextIsOptional);
109+
configFiles.Add((arg, nextIsOptional));
75110
nextIsOptional = false;
76111
}
77112
}
113+
return (configFiles, commandLineArgs.ToArray());
78114
}
79115

80116
private static void NL() => Console.WriteLine();

NpgsqlRestClient/Builder.cs

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -252,19 +252,55 @@ public static void BuildCors()
252252
}
253253

254254
var connectionStringBuilder = new NpgsqlConnectionStringBuilder(connectionString);
255-
if (GetConfigBool("SetApplicationNameInConnection", NpgsqlRestCfg) is true)
255+
if (GetConfigBool("SetApplicationNameInConnection", ConnectionSettingsCfg) is true)
256256
{
257257
connectionStringBuilder.ApplicationName = Instance.Environment.ApplicationName;
258258
}
259259

260-
if (GetConfigBool("UseEnvironmentConnection", NpgsqlRestCfg) is true)
260+
if (GetConfigBool("UseEnvironmentConnection", ConnectionSettingsCfg) is true)
261261
{
262-
connectionStringBuilder.Host ??= Environment.GetEnvironmentVariable("PGHOST") ?? Environment.GetEnvironmentVariable("PGHOSTADDR");
263-
if (int.TryParse(Environment.GetEnvironmentVariable("PGPORT"), out int port) is true)
262+
var whenMissing = GetConfigBool("UseEnvironmentConnectionWhenMissing", ConnectionSettingsCfg);
263+
264+
var hostEnvVar = GetConfigStr("HostEnvVar", ConnectionSettingsCfg);
265+
if (string.IsNullOrEmpty(hostEnvVar) is false && string.IsNullOrEmpty(Environment.GetEnvironmentVariable(hostEnvVar)) is false)
266+
{
267+
if (whenMissing is true || string.IsNullOrEmpty(connectionStringBuilder.Host))
268+
{
269+
connectionStringBuilder.Host = Environment.GetEnvironmentVariable(hostEnvVar);
270+
}
271+
}
272+
var portEnvVar = GetConfigStr("PortEnvVar", ConnectionSettingsCfg);
273+
if (string.IsNullOrEmpty(portEnvVar) is false && int.TryParse(Environment.GetEnvironmentVariable(portEnvVar), out int port) is true)
264274
{
265-
connectionStringBuilder.Port = port;
275+
if (whenMissing is true || connectionStringBuilder.Port != port)
276+
{
277+
connectionStringBuilder.Port = port;
278+
}
279+
}
280+
var dbEnvVar = GetConfigStr("DatabaseEnvVar", ConnectionSettingsCfg);
281+
if (string.IsNullOrEmpty(dbEnvVar) is false && string.IsNullOrEmpty(Environment.GetEnvironmentVariable(dbEnvVar)) is false)
282+
{
283+
if (whenMissing is true || string.IsNullOrEmpty(connectionStringBuilder.Database))
284+
{
285+
connectionStringBuilder.Database = Environment.GetEnvironmentVariable(dbEnvVar);
286+
}
287+
}
288+
var userEnvVar = GetConfigStr("UserEnvVar", ConnectionSettingsCfg);
289+
if (string.IsNullOrEmpty(userEnvVar) is false && string.IsNullOrEmpty(Environment.GetEnvironmentVariable(userEnvVar)) is false)
290+
{
291+
if (whenMissing is true || string.IsNullOrEmpty(connectionStringBuilder.Username))
292+
{
293+
connectionStringBuilder.Username = Environment.GetEnvironmentVariable(userEnvVar);
294+
}
295+
}
296+
var passEnvVar = GetConfigStr("PasswordEnvVar", ConnectionSettingsCfg);
297+
if (string.IsNullOrEmpty(passEnvVar) is false && string.IsNullOrEmpty(Environment.GetEnvironmentVariable(passEnvVar)) is false)
298+
{
299+
if (whenMissing is true || string.IsNullOrEmpty(connectionStringBuilder.Password))
300+
{
301+
connectionStringBuilder.Password = Environment.GetEnvironmentVariable(passEnvVar);
302+
}
266303
}
267-
connectionStringBuilder.Database ??= Environment.GetEnvironmentVariable("PGDATABASE");
268304
}
269305

270306
connectionString = connectionStringBuilder.ConnectionString;

NpgsqlRestClient/Config.cs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ public static class Config
77
{
88
public static IConfigurationRoot Cfg { get; private set; } = null!;
99
public static IConfigurationSection NpgsqlRestCfg { get; private set; } = null!;
10+
public static IConfigurationSection ConnectionSettingsCfg { get; private set; } = null!;
11+
public static bool UseConnectionApplicationNameWithUsername { get; private set; }
1012
public static IConfigurationSection AuthCfg { get; private set; } = null!;
1113
public static string CurrentDir => Directory.GetCurrentDirectory();
1214

@@ -16,9 +18,11 @@ public static void Build(string[] args)
1618
var tempBuilder = new ConfigurationBuilder();
1719
IConfigurationRoot tempCfg;
1820

19-
if (args.Length > 0)
21+
var (configFiles, commandLineArgs) = Arguments.BuildFromArgs(args);
22+
23+
if (configFiles.Count > 0)
2024
{
21-
foreach (var (fileName, optional) in Arguments.EnumerateConfigFiles(args))
25+
foreach (var (fileName, optional) in configFiles)
2226
{
2327
tempBuilder.AddJsonFile(Path.GetFullPath(fileName, CurrentDir), optional: optional);
2428
}
@@ -41,24 +45,28 @@ public static void Build(string[] args)
4145
configBuilder = new ConfigurationBuilder();
4246
}
4347

44-
if (args.Length > 0)
48+
if (configFiles.Count > 0)
4549
{
46-
foreach (var (fileName, optional) in Arguments.EnumerateConfigFiles(args))
50+
foreach (var (fileName, optional) in configFiles)
4751
{
4852
configBuilder.AddJsonFile(Path.GetFullPath(fileName, CurrentDir), optional: optional);
4953
}
54+
configBuilder.AddCommandLine(commandLineArgs);
5055
Cfg = configBuilder.Build();
5156
}
5257
else
5358
{
5459
Cfg = configBuilder
55-
.AddJsonFile("appsettings.json", optional: false)
56-
.AddJsonFile("appsettings.Development.json", optional: true)
60+
.AddJsonFile(Path.GetFullPath("appsettings.json", CurrentDir), optional: false)
61+
.AddJsonFile(Path.GetFullPath("appsettings.Development.json", CurrentDir), optional: true)
62+
.AddCommandLine(commandLineArgs)
5763
.Build();
5864
}
5965

6066
NpgsqlRestCfg = Cfg.GetSection("NpgsqlRest");
6167
AuthCfg = NpgsqlRestCfg.GetSection("AuthenticationOptions");
68+
ConnectionSettingsCfg = Cfg.GetSection("ConnectionSettings");
69+
UseConnectionApplicationNameWithUsername = GetConfigBool("UseJsonApplicationName", ConnectionSettingsCfg);
6270
}
6371

6472
public static bool Exists(this IConfigurationSection? section)

NpgsqlRestClient/NpgsqlRestClient.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<InvariantGlobalization>true</InvariantGlobalization>
88
<NoDefaultLaunchSettingsFile>true</NoDefaultLaunchSettingsFile>
99
<PublishAot>true</PublishAot>
10-
<Version>1.3.0</Version>
10+
<Version>1.4.0</Version>
1111
</PropertyGroup>
1212

1313
<ItemGroup>

NpgsqlRestClient/appsettings.json

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
//
2222
// Expose current configuration to the endpoint for debugging and inspection. Note, the password in the connection string is not exposed.
2323
//
24-
"ExposeAsEndpoint": "/config",
24+
//"ExposeAsEndpoint": "/config",
25+
"ExposeAsEndpoint": null,
2526
//
2627
// Add the environment variables to configuration first.
2728
//
@@ -35,6 +36,51 @@
3536
"Default": ""
3637
},
3738

39+
"ConnectionSettings": {
40+
//
41+
// Use the environment variables to set the connection string parameters. Default environment variables are defined below.
42+
// Connection parameter will be set from the environment variables this option is enabled and the environment variables are set.
43+
// Note: When this option is enabled and these environment variables are set, connection string doesn't have to be defined at all and it will be created from the environment variables.
44+
//
45+
"UseEnvironmentConnection": true,
46+
//
47+
// Use the environment variables to set the connection string parameters when the connection string section is missing.
48+
// Set to true to use the environment variablesto override the connection string parameters.
49+
//
50+
"UseEnvironmentConnectionWhenMissing": false,
51+
//
52+
// Name of the host environment variable.
53+
//
54+
"HostEnvVar": "PGHOST",
55+
//
56+
// Name of the port environment variable.
57+
//
58+
"PortEnvVar": "PGPORT",
59+
//
60+
// Name of the database environment variable.
61+
//
62+
"DatabaseEnvVar": "PGDATABASE",
63+
//
64+
// The user name to use for the connection string parameters.
65+
//
66+
"UserEnvVar": "PGUSER",
67+
//
68+
// Name of the password environment variable.
69+
//
70+
"PasswordEnvVar": "PGPASSWORD",
71+
//
72+
// Sets the ApplicationName connection property in the connection string to the value of the ApplicationName configuration.
73+
// Note: This option is ignored if the UseJsonApplicationName option is enabled.
74+
//
75+
"SetApplicationNameInConnection": true,
76+
//
77+
// Sets the ApplicationName connection property dynamically on every request in the following format:
78+
// {"app": [Application Name], "uid": [User Id for authenticated users or NULL], "id": [Valud of X-Execution-Id request header or NULL]}
79+
// Note: ApplicationName connection property is limited to 64 characters.
80+
//
81+
"UseJsonApplicationName": false
82+
},
83+
3884
//
3985
// Specify the urls the web host will listen on. See https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.hosting.hostingabstractionswebhostbuilderextensions.useurls?view=aspnetcore-8.0
4086
//
@@ -265,26 +311,6 @@
265311
//
266312
"ConnectionName": null,
267313
//
268-
// If the connection string is not found, empty, or missing host, port or database, the connection string is created from the environment variables.
269-
// See https://www.postgresql.org/docs/current/libpq-envars.html for the list of the environment variables.
270-
//
271-
// Note: Npgsql will use the environment variables by default but only for the small set of the connection string parameters like username and password (see https://www.npgsql.org/doc/connection-string-parameters.html#environment-variables).
272-
// Set this option to true to use environment variables for host, port and database as well.
273-
// When this option is enabled and these environment variables are set, connection string doesn't have to be defined at all and it will be created from the environment variables.
274-
//
275-
"UseEnvironmentConnection": true,
276-
//
277-
// Sets the ApplicationName connection property in the connection string to the value of the ApplicationName configuration.
278-
// Note: This option is ignored if the UseJsonApplicationName option is enabled.
279-
//
280-
"SetApplicationNameInConnection": true,
281-
//
282-
// Sets the ApplicationName connection property dynamically on every request in the following format:
283-
// {"app": [Application Name], "uid": [User Id for authenticated users or NULL], "id": [Valud of X-Execution-Id request header or NULL]}
284-
// Note: ApplicationName connection property is limited to 64 characters.
285-
//
286-
"UseJsonApplicationName": true,
287-
//
288314
// See https://vb-consulting.github.io/npgsqlrest/options/#schemasimilarto
289315
//
290316
"SchemaSimilarTo": null,

client.md

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -62,21 +62,40 @@ See the [default configuration file](https://vb-consulting.github.io/npgsqlrest/
6262
```console
6363
npgsqlrest --help
6464
Usage:
65-
npgsqlrest Run with the default configuration files: appsettings.json (required) and appsettings.Development.json (optional).
66-
npgsqlrest [files...] Run with the custom configuration files. All configuration files are required.
67-
npgsqlrest [file1 -o file2...] Use the -o switch to mark the next configuration file as optional. The first file after the -o switch is optional.
68-
npgsqlrest [file1 --optional file2...] Use --optional switch to mark the next configuration file as optional. The first file after the --optional switch is optional.
65+
npgsqlrest Run with the default configuration files: appsettings.json (required) and
66+
appsettings.Development.json (optional).
67+
npgsqlrest [files...] Run with the custom configuration files. All configuration files are required.
68+
npgsqlrest [file1 -o file2...] Use the -o switch to mark the next configuration file as optional. The first
69+
file after the -o switch is optional.
70+
npgsqlrest [file1 --optional file2...] Use --optional switch to mark the next configuration file as optional. The
71+
first file after the --optional switch is optional.
72+
Note: Values in the later file will override the values in the previous one.
73+
npgsqlrest [--key=value] Override the configuration with this key with a new value (case insensitive,
74+
use : to separate sections).
75+
76+
npgsqlrest -v, --version Show version information.
77+
npgsqlrest -h, --help Show command line help.
78+
79+
80+
Examples:
81+
Example: use two config files npgsqlrest appsettings.json appsettings.Development.json
82+
Example: second config file optional npgsqlrest appsettings.json -o appsettings.Development.json
83+
Example: override ApplicationName config npgsqlrest --applicationname=Test
84+
Example: override Auth:CookieName config npgsqlrest --auth:cookiename=Test
85+
```
6986

70-
npgsqlrest -v, --version Show version information.
71-
npgsqlrest -h, --help Show command line help.
87+
## Changelog
7288

73-
Note: Values in the later file will override the values in the previous one.
89+
## 1.4.0
7490

75-
Example: npgsqlrest appsettings.json appsettings.Development.json
76-
Example: npgsqlrest appsettings.json -o appsettings.Development.json
77-
```
91+
See the [full diff here](https://github.com/vb-consulting/NpgsqlRest/compare/client-1.3.0...client-1.4.0)
7892

79-
## Changelog
93+
- Added new configuration section: `ConnectionSettings` and moved `UseEnvironmentConnection`, `SetApplicationNameInConnection`, and `UseJsonApplicationName` from `NpgsqlRest` to `ConnectionSettings`.
94+
- Added connections settings for customize connection parameters environment variable names (`HostEnvVar`, `PortEnvVar`, `DatabaseEnvVar`, `UserEnvVar` and `PasswordEnvVar`). Some Docker environments have different environment variable names.
95+
- Added connections settings `"UseEnvironmentConnectionWhenMissing": false` to be able to override connection string with environment variable names and vice versa.
96+
- Added support for overriding configuration settings from the command line. Command line configuration has to have this format: `--key=value`. See updated help for more info.
97+
- Configuration value `ExposeAsEndpoint` is now set to NULL (disabled) as the default configuration. This may be enabled in the development environment.
98+
- Fix: Default configuration files `appsettings.json` and optional `appsettings.Development.json` are now loaded from the same directory as all others (current directory as opposed to the exe location dir).
8099

81100
## 1.3.0
82101

0 commit comments

Comments
 (0)