Skip to content

Commit 9de59d8

Browse files
committed
Config changes
1 parent 99f543b commit 9de59d8

15 files changed

Lines changed: 495 additions & 16 deletions

sample.yaml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# the connection string to the database
2+
connectionString: "Data Source=(local);Initial Catalog=Tracker;Integrated Security=True"
3+
4+
# the database provider name. Default:SqlServer
5+
provider: SqlServer
6+
7+
# config name to read the connection string from the user secrets file
8+
connectionName: "ConnectionStrings:Generator"
9+
10+
# the user secret identifier, can be shared with .net core project
11+
userSecretsId: "984ef0cf-2b22-4fd1-876d-e01499da4c1f"
12+
13+
# the directory to output the configuration. Default is current.
14+
outputDirectory: .\
15+
16+
# tables to include or empty to include all
17+
tables:
18+
- Priority
19+
- Status
20+
- Task
21+
- User
22+
23+
# schemas to include or empty to include all
24+
schemas:
25+
- dbo
26+
27+
# exclude tables or columns
28+
exclude:
29+
# list of expressions for tables to exclude, source is Schema.TableName
30+
tables:
31+
- exact: dbo.SchemaVersions
32+
- regex: dbo\.SchemaVersions$
33+
# list of expressions for columns to exclude, source is Schema.TableName.ColumnName
34+
columns:
35+
- exact: dbo.SchemaVersions\.Version
36+
- regex: dbo\.SchemaVersions\.Version$
37+
38+
# how to generate entity class names from the table name. Preserve|Plural|Singular. Default: Singular
39+
entityNaming: Singular
40+
41+
# how to generate relationship collections names for the entity. Default: Plural
42+
relationshipNaming: Plural
43+
44+
# Rename entities and properties with regular expressions. Matched expressions will be removed.
45+
renaming:
46+
entities:
47+
- ^(sp|tbl|udf|vw)_
48+
properties:
49+
- ^{Table.Name}(?=Id|Name)

src/DbApiBuilderEntityGenerator.Core/ConfigurationSerializer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public ConfigurationSerializer(ILogger<ConfigurationSerializer> logger)
2525
/// <summary>
2626
/// The options file name. Default 'generation.yml'
2727
/// </summary>
28-
public const string OptionsFileName = "generation.yml";
28+
public const string OptionsFileName = "sample.yaml";
2929

3030
/// <summary>
3131
/// Loads the options file using the specified <paramref name="directory"/> and <paramref name="file"/>.
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
using System;
2+
using DbApiBuilderEntityGenerator.Core.Options;
3+
using DbApiBuilderEntityGenerator.Core.Serialization;
4+
5+
namespace DbApiBuilderEntityGenerator.Core;
6+
7+
public static class OptionMapper
8+
{
9+
public static GeneratorOptions Map(GeneratorModel generator)
10+
{
11+
var options = new GeneratorOptions();
12+
options.Variables.ShouldEvaluate = false;
13+
options.ConnectionName = generator.ConnectionName;
14+
options.ConnectionString = generator.ConnectionString;
15+
options.ConnectionName = generator.ConnectionName;
16+
options.UserSecretsId = generator.UserSecretsId;
17+
MapList(options.Tables, generator.Tables);
18+
MapList(options.Schemas, generator.Schemas);
19+
MapDatabaseMatch(options.Exclude, generator.Exclude);
20+
options.EntityNaming = generator.EntityNaming;
21+
options.RelationshipNaming = generator.RelationshipNaming;
22+
MapSelection(options.Renaming, generator.Renaming);
23+
24+
options.Variables.ShouldEvaluate = true;
25+
26+
return options;
27+
}
28+
private static void MapSelection(SelectionOptions option, SelectionModel? selection)
29+
{
30+
if (selection == null)
31+
return;
32+
33+
MapList(option.Entities, selection.Entities, (match) =>
34+
{
35+
var prefix = OptionsBase.AppendPrefix(option.Prefix, $"Entity{option.Entities.Count:0000}");
36+
return MapMatch(option.Variables, match, prefix);
37+
});
38+
39+
MapList(option.Properties, selection.Properties, (match) =>
40+
{
41+
var prefix = OptionsBase.AppendPrefix(option.Prefix, $"Property{option.Properties.Count:0000}");
42+
return MapMatch(option.Variables, match, prefix);
43+
});
44+
}
45+
private static void MapList<T>(IList<T> targetList, IList<T>? sourceList)
46+
{
47+
if (sourceList == null || sourceList.Count == 0)
48+
return;
49+
50+
foreach (var source in sourceList)
51+
targetList.Add(source);
52+
}
53+
54+
private static void MapList<TTarget, TSource>(IList<TTarget> targetList, IList<TSource>? sourceList, Func<TSource, TTarget> factory)
55+
{
56+
if (sourceList == null || sourceList.Count == 0)
57+
return;
58+
59+
foreach (var source in sourceList)
60+
{
61+
var target = factory(source);
62+
targetList.Add(target);
63+
}
64+
}
65+
66+
private static MatchOptions MapMatch(VariableDictionary variables, MatchModel match, string? prefix)
67+
{
68+
return new MatchOptions()
69+
{
70+
Exact = match.Exact,
71+
Expression = match.Expression
72+
};
73+
}
74+
75+
private static void MapDatabaseMatch(DatabaseMatchOptions option, DatabaseMatchModel? match)
76+
{
77+
if (match == null)
78+
return;
79+
80+
MapList(option.Tables, match.Tables, (match) =>
81+
{
82+
var prefix = OptionsBase.AppendPrefix(option.Prefix, $"Table{option.Tables?.Count:0000}");
83+
return MapMatch(option.Variables, match, prefix);
84+
});
85+
86+
MapList(option.Columns, match.Columns, (match) =>
87+
{
88+
var prefix = OptionsBase.AppendPrefix(option.Prefix, $"Column{option.Columns?.Count:0000}");
89+
return MapMatch(option.Variables, match, prefix);
90+
});
91+
}
92+
}

src/DbApiBuilderEntityGenerator.Core/Options/DatabaseMatchOptions.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ public class DatabaseMatchOptions : OptionsBase
1212
/// </summary>
1313
/// <param name="variables">A dictionary of variables used to configure the matching options. Cannot be null.</param>
1414
/// <param name="prefix">An optional prefix used to filter or qualify the matching criteria. Can be null.</param>
15-
public DatabaseMatchOptions(VariableDictionary variables, string? prefix)
16-
: base(variables, prefix)
15+
public DatabaseMatchOptions()
1716
{
1817
Tables = [];
1918
Columns = [];

src/DbApiBuilderEntityGenerator.Core/Options/GeneratorOptions.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,17 @@ public class GeneratorOptions : OptionsBase
1111
/// <summary>
1212
/// Initializes a new instance of the <see cref="GeneratorOptions"/> class.
1313
/// </summary>
14-
public GeneratorOptions(VariableDictionary variables,
15-
string? prefix) : base(variables, null)
14+
public GeneratorOptions()
1615
{
17-
Variables = variables;
16+
Variables = new VariableDictionary();
1817
Provider = DatabaseProviders.SqlServer;
1918
Directory = @".\";
2019
Tables = [];
2120
Schemas = [];
22-
Exclude = new DatabaseMatchOptions(Variables, Prefix);
21+
Exclude = new DatabaseMatchOptions();
2322
EntityNaming = EntityNaming.Singular;
2423
RelationshipNaming = RelationshipNaming.Plural;
24+
Renaming = new SelectionOptions();
2525
}
2626

2727
[YamlIgnore]

src/DbApiBuilderEntityGenerator.Core/Options/MatchOptions.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ public class MatchOptions : OptionsBase
1515
/// </summary>
1616
/// <param name="variables">The shared variables dictionary.</param>
1717
/// <param name="prefix">The variable key prefix.</param>
18-
public MatchOptions(VariableDictionary variables, string? prefix)
19-
: base(variables, prefix)
18+
public MatchOptions()
2019
{
2120
}
2221

src/DbApiBuilderEntityGenerator.Core/Options/OptionsBase.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,11 @@ public class OptionsBase
1212
/// </summary>
1313
/// <param name="variables">The shared variables dictionary.</param>
1414
/// <param name="prefix">The variable key prefix.</param>
15-
public OptionsBase(VariableDictionary variables, string? prefix)
15+
public OptionsBase()
1616
{
17-
ArgumentNullException.ThrowIfNull(variables);
1817

1918
}
20-
public VariableDictionary Variables { get; }
19+
public VariableDictionary Variables { get; } = new VariableDictionary();
2120

2221
public string? Prefix { get; }
2322

src/DbApiBuilderEntityGenerator.Core/Options/SelectionOptions.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ public class SelectionOptions : OptionsBase
1010
/// <summary>
1111
/// Initializes a new instance of the <see cref="SelectionOptions"/> class.
1212
/// </summary>
13-
public SelectionOptions(VariableDictionary variables, string? prefix)
14-
: base(variables, prefix)
13+
public SelectionOptions()
1514
{
1615
Entities = [];
1716
Properties = [];
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
using System;
2+
using System.Text.Json;
3+
using DbApiBuilderEntityGenerator.Core.Extensions;
4+
using Microsoft.Extensions.Configuration;
5+
using Microsoft.Extensions.Configuration.UserSecrets;
6+
7+
namespace DbApiBuilderEntityGenerator.Core;
8+
9+
public class SecretsStore
10+
{
11+
private readonly string _secretsFilePath;
12+
private readonly IDictionary<string, string?> _secrets;
13+
14+
public SecretsStore(string userSecretsId)
15+
{
16+
if (string.IsNullOrEmpty(userSecretsId))
17+
throw new ArgumentException("Value cannot be null or empty.", nameof(userSecretsId));
18+
19+
_secretsFilePath = PathHelper.GetSecretsPathFromSecretsId(userSecretsId);
20+
21+
// workaround bug in configuration
22+
var secretDir = Path.GetDirectoryName(_secretsFilePath);
23+
if (secretDir.HasValue() && !Directory.Exists(secretDir))
24+
Directory.CreateDirectory(secretDir);
25+
26+
_secrets = Load(userSecretsId);
27+
}
28+
29+
public string? this[string key] => _secrets[key];
30+
31+
public int Count => _secrets.Count;
32+
33+
public bool ContainsKey(string key) => _secrets.ContainsKey(key);
34+
35+
public IEnumerable<KeyValuePair<string, string?>> AsEnumerable() => _secrets;
36+
37+
public void Clear() => _secrets.Clear();
38+
39+
public void Set(string key, string value) => _secrets[key] = value;
40+
41+
public void Remove(string key)
42+
{
43+
_secrets.Remove(key);
44+
}
45+
46+
public virtual void Save()
47+
{
48+
var secretDir = Path.GetDirectoryName(_secretsFilePath);
49+
if (secretDir.HasValue() && !Directory.Exists(secretDir))
50+
Directory.CreateDirectory(secretDir);
51+
52+
var options = new JsonWriterOptions
53+
{
54+
Indented = true
55+
};
56+
57+
using var stream = File.Create(_secretsFilePath);
58+
using var writer = new Utf8JsonWriter(stream, options);
59+
60+
writer.WriteStartObject();
61+
62+
foreach (var secret in _secrets.AsEnumerable())
63+
writer.WriteString(secret.Key, secret.Value);
64+
65+
writer.WriteEndObject();
66+
writer.Flush();
67+
}
68+
69+
protected virtual IDictionary<string, string?> Load(string userSecretsId)
70+
{
71+
return new ConfigurationBuilder()
72+
.AddJsonFile(_secretsFilePath, optional: true)
73+
.Build()
74+
.AsEnumerable()
75+
.Where(i => i.Value != null)
76+
.ToDictionary(i => i.Key, i => i.Value, StringComparer.OrdinalIgnoreCase);
77+
}
78+
79+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System;
2+
using McMaster.Extensions.CommandLineUtils;
3+
using Microsoft.Extensions.Logging;
4+
5+
namespace DbApiBuilderEntityGenerator;
6+
7+
[HelpOption("--help")]
8+
public abstract class CommandBase
9+
{
10+
11+
protected CommandBase(ILoggerFactory logger, IConsole console)
12+
{
13+
Logger = logger.CreateLogger(GetType());
14+
Console = console;
15+
}
16+
17+
protected ILogger Logger { get; }
18+
19+
protected IConsole Console { get; }
20+
21+
protected abstract int OnExecute(CommandLineApplication application);
22+
23+
}

0 commit comments

Comments
 (0)