Skip to content

Commit c749625

Browse files
committed
Commit test files
1 parent 9de59d8 commit c749625

32 files changed

Lines changed: 2002 additions & 3 deletions
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
using System;
2+
using DbApiBuilderEntityGenerator.Core.Extensions;
3+
using DbApiBuilderEntityGenerator.Core.Options;
4+
using Microsoft.EntityFrameworkCore.Design;
5+
using Microsoft.EntityFrameworkCore.Scaffolding;
6+
using Microsoft.EntityFrameworkCore.Scaffolding.Metadata;
7+
using Microsoft.EntityFrameworkCore.Storage;
8+
using Microsoft.Extensions.DependencyInjection;
9+
using Microsoft.Extensions.Logging;
10+
11+
namespace DbApiBuilderEntityGenerator.Core;
12+
13+
public class CodeGenerator : ICodeGenerator
14+
{
15+
private readonly ILoggerFactory _loggerFactory;
16+
private readonly ILogger _logger;
17+
private readonly ModelGenerator _modelGenerator;
18+
19+
public CodeGenerator(ILoggerFactory loggerFactory)
20+
{
21+
_loggerFactory = loggerFactory;
22+
_logger = loggerFactory.CreateLogger<CodeGenerator>();
23+
_modelGenerator = new ModelGenerator(loggerFactory);
24+
// _synchronizer = new SourceSynchronizer(loggerFactory);
25+
}
26+
27+
public GeneratorOptions Options { get; set; } = null!;
28+
public bool Generate(GeneratorOptions options)
29+
{
30+
Options = options ?? throw new ArgumentNullException(nameof(options));
31+
32+
var databaseProviders = GetDatabaseProviders();
33+
var databaseModel = GetDatabaseModel(databaseProviders.factory);
34+
if (databaseModel == null)
35+
throw new InvalidOperationException("Failed to create database model");
36+
37+
_logger.LogInformation("Loaded database model for: {databaseName}", databaseModel.DatabaseName);
38+
39+
var context = _modelGenerator.Generate(Options, databaseModel, databaseProviders.mapping);
40+
41+
return true;
42+
}
43+
private DatabaseModel GetDatabaseModel(IDatabaseModelFactory factory)
44+
{
45+
_logger.LogInformation("Loading database model ...");
46+
47+
48+
var connectionString = ResolveConnectionString(Options.ConnectionString, Options.UserSecretsId, Options.ConnectionName);
49+
if (string.IsNullOrEmpty(connectionString))
50+
throw new InvalidOperationException("Could not find connection string.");
51+
52+
var options = new DatabaseModelFactoryOptions(Options.Tables, Options.Schemas);
53+
54+
return factory.Create(connectionString, options);
55+
}
56+
57+
private static string? ResolveConnectionString(string? connectionString,
58+
string? userSecretsId,
59+
string? connectionName)
60+
{
61+
if (connectionString.HasValue())
62+
return connectionString;
63+
64+
if (userSecretsId.HasValue() && connectionName.HasValue())
65+
{
66+
var secretsStore = new SecretsStore(userSecretsId);
67+
if (secretsStore.ContainsKey(connectionName))
68+
return secretsStore[connectionName];
69+
}
70+
71+
throw new InvalidOperationException("Could not find connection string.");
72+
}
73+
74+
private (IDatabaseModelFactory factory, IRelationalTypeMappingSource mapping) GetDatabaseProviders()
75+
{
76+
var provider = Options.Provider;
77+
78+
_logger.LogDebug("Creating database model factory for: {provider}", provider);
79+
80+
// start a new service container to create the database model factory
81+
var services = new ServiceCollection()
82+
.AddSingleton(_loggerFactory)
83+
.AddEntityFrameworkDesignTimeServices();
84+
85+
switch (provider)
86+
{
87+
case DatabaseProviders.SqlServer:
88+
ConfigureSqlServerServices(services);
89+
break;
90+
case DatabaseProviders.PostgreSQL:
91+
ConfigurePostgresServices(services);
92+
break;
93+
case DatabaseProviders.MySQL:
94+
ConfigureMySqlServices(services);
95+
break;
96+
case DatabaseProviders.Sqlite:
97+
ConfigureSqliteServices(services);
98+
break;
99+
case DatabaseProviders.Oracle:
100+
ConfigureOracleServices(services);
101+
break;
102+
default:
103+
throw new NotSupportedException($"The specified provider '{provider}' is not supported.");
104+
}
105+
106+
var serviceProvider = services
107+
.BuildServiceProvider();
108+
109+
var databaseModelFactory = serviceProvider
110+
.GetRequiredService<IDatabaseModelFactory>();
111+
112+
var typeMappingSource = serviceProvider
113+
.GetRequiredService<IRelationalTypeMappingSource>();
114+
115+
return (databaseModelFactory, typeMappingSource);
116+
}
117+
private static void ConfigureMySqlServices(IServiceCollection services)
118+
{
119+
var designTimeServices = new Pomelo.EntityFrameworkCore.MySql.Design.Internal.MySqlDesignTimeServices();
120+
designTimeServices.ConfigureDesignTimeServices(services);
121+
services.AddEntityFrameworkMySqlNetTopologySuite();
122+
}
123+
124+
private static void ConfigurePostgresServices(IServiceCollection services)
125+
{
126+
var designTimeServices = new Npgsql.EntityFrameworkCore.PostgreSQL.Design.Internal.NpgsqlDesignTimeServices();
127+
designTimeServices.ConfigureDesignTimeServices(services);
128+
services.AddEntityFrameworkNpgsqlNetTopologySuite();
129+
}
130+
131+
private static void ConfigureSqlServerServices(IServiceCollection services)
132+
{
133+
var designTimeServices = new Microsoft.EntityFrameworkCore.SqlServer.Design.Internal.SqlServerDesignTimeServices();
134+
designTimeServices.ConfigureDesignTimeServices(services);
135+
services.AddEntityFrameworkSqlServerNetTopologySuite();
136+
}
137+
138+
private static void ConfigureSqliteServices(IServiceCollection services)
139+
{
140+
var designTimeServices = new Microsoft.EntityFrameworkCore.Sqlite.Design.Internal.SqliteDesignTimeServices();
141+
designTimeServices.ConfigureDesignTimeServices(services);
142+
services.AddEntityFrameworkSqliteNetTopologySuite();
143+
}
144+
145+
private static void ConfigureOracleServices(IServiceCollection services)
146+
{
147+
var designTimeServices = new Oracle.EntityFrameworkCore.Design.Internal.OracleDesignTimeServices();
148+
designTimeServices.ConfigureDesignTimeServices(services);
149+
}
150+
}

src/DbApiBuilderEntityGenerator.Core/DbApiBuilderEntityGenerator.Core.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
<PackageReference Include="YamlDotNet" Version="16.3.0" />
2525
</ItemGroup>
2626
<ItemGroup>
27+
<Folder Include="Metadata\" />
28+
<Folder Include="Metadata\Generation\" />
2729
<Folder Include="Serialization\" />
2830
</ItemGroup>
2931
</Project>
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using System;
2+
3+
namespace DbApiBuilderEntityGenerator.Core.Extensions;
4+
5+
/// <summary>
6+
/// Provides extension methods for <see cref="IEnumerable{T}"/> to assist with string formatting and conversion.
7+
/// </summary>
8+
public static partial class EnumerableExtensions
9+
{
10+
/// <summary>
11+
/// Concatenates the members of a sequence, using the specified delimiter between each member, and returns the resulting string.
12+
/// </summary>
13+
/// <typeparam name="T">
14+
/// The type of the elements in the sequence.
15+
/// </typeparam>
16+
/// <param name="values">
17+
/// The sequence of values to concatenate. Each value will be converted to a string using its <c>ToString()</c> method.
18+
/// </param>
19+
/// <param name="delimiter">
20+
/// The string to use as a delimiter. If <c>null</c>, a comma (",") is used by default.
21+
/// </param>
22+
/// <returns>
23+
/// A string that consists of the elements in <paramref name="values"/> delimited by the <paramref name="delimiter"/> string.
24+
/// If <paramref name="values"/> is empty, returns <see cref="string.Empty"/>.
25+
/// </returns>
26+
public static string ToDelimitedString<T>(this IEnumerable<T?> values, string? delimiter = ",")
27+
=> string.Join(delimiter ?? ",", values);
28+
29+
/// <summary>
30+
/// Concatenates the members of a sequence of strings, using the specified delimiter between each member, and returns the resulting string.
31+
/// </summary>
32+
/// <param name="values">
33+
/// The sequence of string values to concatenate. <c>null</c> values are treated as empty strings.
34+
/// </param>
35+
/// <param name="delimiter">
36+
/// The string to use as a delimiter. If <c>null</c>, a comma (",") is used by default.
37+
/// </param>
38+
/// <returns>
39+
/// A string that consists of the elements in <paramref name="values"/> delimited by the <paramref name="delimiter"/> string.
40+
/// If <paramref name="values"/> is empty, returns <see cref="string.Empty"/>.
41+
/// </returns>
42+
public static string ToDelimitedString(this IEnumerable<string?> values, string? delimiter = ",")
43+
=> string.Join(delimiter ?? ",", values);
44+
45+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using System;
2+
using DbApiBuilderEntityGenerator.Core.Options;
3+
4+
namespace DbApiBuilderEntityGenerator.Core;
5+
6+
public interface ICodeGenerator
7+
{
8+
bool Generate(GeneratorOptions options);
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace DbApiBuilderEntityGenerator.Core.Metadata.Generation;
2+
3+
public enum Cardinality
4+
{
5+
ZeroOrOne,
6+
One,
7+
Many
8+
9+
}

0 commit comments

Comments
 (0)