Skip to content

Commit 488b920

Browse files
author
Carlos José jiménez bermúdez
committed
Move some more code.
1 parent ca0c07a commit 488b920

File tree

8 files changed

+317
-5
lines changed

8 files changed

+317
-5
lines changed

DbReflector.CLI/DbReflector.CLI.csproj

+4
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,8 @@
1414
<ProjectReference Include="..\DbReflector.Core\DbReflector.Core.csproj" />
1515
</ItemGroup>
1616

17+
<ItemGroup>
18+
<Folder Include="Logging\" />
19+
</ItemGroup>
20+
1721
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using System.Collections.Generic;
2+
using DbReflector.CodeGeneration.Models;
3+
4+
namespace DbReflector.Core.MetadataMappers
5+
{
6+
public interface IPostgresMetadataMapper
7+
{
8+
Database CreateGeneratorModel(string connectionString, string dbName, List<string> tablesToIgnore, string schema = "public");
9+
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using System.Collections.Generic;
2+
using DbReflector.CodeGeneration.Models;
3+
4+
namespace DbReflector.Core.MetadataMappers
5+
{
6+
public interface ISqlServerMetadataMapper
7+
{
8+
Database CreateGeneratorModel(string connectionString, string dbName, List<string> tablesToIgnore, string schema = "dbo");
9+
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using Humanizer;
5+
using DbReflector.Databases;
6+
using DbReflector.Databases.Exceptions;
7+
using DbReflector.Databases.Models;
8+
using DbReflector.CodeGeneration.Models;
9+
using DbReflector.Common;
10+
11+
namespace DbReflector.Core.MetadataMappers
12+
{
13+
public class PostgresMetadataMapper : IPostgresMetadataMapper
14+
{
15+
private readonly IDbScanner<PostgresTable, PostgresColumn> _databaseScanner;
16+
17+
public PostgresMetadataMapper(IDbScanner<PostgresTable, PostgresColumn> databaseScanner)
18+
{
19+
_databaseScanner = databaseScanner;
20+
}
21+
22+
public Database CreateGeneratorModel(string connectionString, string dbName, List<string> tablesToIgnore, string schema = "public")
23+
{
24+
var tableList = new List<Table>();
25+
26+
try
27+
{
28+
var tablesMetadata = _databaseScanner.GetTablesFromDatabase(dbName, schema);
29+
var columnsMetadata = _databaseScanner.GetColumnsFromDatabase(dbName, schema);
30+
var columnsWithPrimaryKeys = _databaseScanner.GetColumnsFromDatabaseWithPK(dbName, schema);
31+
32+
foreach (var table in tablesMetadata)
33+
{
34+
if (tablesToIgnore.Contains(table.table_name))
35+
continue;
36+
37+
var tableColumns = new List<Column>();
38+
39+
var columnsInTable = columnsMetadata.Where(x => x.table_name == table.table_name);
40+
41+
var columnsGeneratorModel = columnsInTable.Select(column =>
42+
{
43+
bool isNull = column.is_nullable == "YES";
44+
bool isPrimary = columnsWithPrimaryKeys.Any(col => col.column_name == column.column_name);
45+
46+
bool isIdentity = column.is_identity == "YES";
47+
48+
var type = new ColumnType(column.udt_name, isNull, SupportedDatabases.Postgres);
49+
50+
return new Column(column.column_name, type, isPrimary, isIdentity);
51+
}).ToList();
52+
53+
tableList.Add(new Table(table.table_name, columnsGeneratorModel, SupportedDatabases.Postgres));
54+
}
55+
56+
return new Database
57+
{
58+
Name = dbName,
59+
FormattedName = dbName.Replace("-", "_").Pascalize(),
60+
Tables = tableList
61+
};
62+
}
63+
catch(Exception e)
64+
{
65+
throw new DatabaseScanningException(@"The metadata mapper failed to read the database.
66+
Make sure your connection string is valid or that the user has the proper permissions.", e);
67+
}
68+
}
69+
}
70+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
using Humanizer;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using DbReflector.Databases;
6+
using DbReflector.Databases.Exceptions;
7+
using DbReflector.Databases.Models;
8+
using DbReflector.CodeGeneration.Models;
9+
using DbReflector.Common;
10+
11+
namespace DbReflector.Core.MetadataMappers
12+
{
13+
public class SqlServerMetadataMapper : ISqlServerMetadataMapper
14+
{
15+
private readonly IDbScanner<SqlServerTable, SqlServerColumn> _databaseScanner;
16+
17+
public SqlServerMetadataMapper(IDbScanner<SqlServerTable, SqlServerColumn> databaseScanner)
18+
{
19+
_databaseScanner = databaseScanner;
20+
}
21+
22+
public Database CreateGeneratorModel(string connectionString, string dbName, List<string> tablesToIgnore, string schema = "dbo")
23+
{
24+
var tableList = new List<Table>();
25+
26+
try
27+
{
28+
var tablesMetadata = _databaseScanner.GetTablesFromDatabase(dbName, schema);
29+
var columnsMetadata = _databaseScanner.GetColumnsFromDatabase(dbName, schema);
30+
var columnsWithPrimaryKeys = _databaseScanner.GetColumnsFromDatabaseWithPK(dbName, schema);
31+
32+
foreach(var table in tablesMetadata)
33+
{
34+
if(tablesToIgnore.Contains(table.TABLE_NAME))
35+
continue;
36+
37+
var tableColumns = new List<Column>();
38+
39+
var columnsInTable = columnsMetadata.Where(x => x.TABLE_NAME == table.TABLE_NAME);
40+
41+
var columnsGeneratorModel = columnsInTable.Select(column =>
42+
{
43+
bool isNull = column.IS_NULLABLE == "YES";
44+
bool isPrimary = columnsWithPrimaryKeys.Any(col => col.COLUMN_NAME == column.COLUMN_NAME);
45+
46+
bool isIdentity = column.IS_IDENTITY == "YES";
47+
48+
var type = new ColumnType(column.DATA_TYPE, isNull, SupportedDatabases.SqlServer);
49+
50+
return new Column(column.COLUMN_NAME, type, isPrimary, isIdentity);
51+
}).ToList();
52+
53+
tableList.Add(new Table(table.TABLE_NAME, columnsGeneratorModel, SupportedDatabases.SqlServer));
54+
}
55+
56+
return new Database
57+
{
58+
Name = dbName,
59+
FormattedName = dbName.Replace("-", "_").Pascalize(),
60+
Tables = tableList
61+
};
62+
}
63+
catch(Exception e)
64+
{
65+
throw new DatabaseScanningException(@"The metadata mapper failed to read the database.
66+
Make sure your connection string is valid or that the user has the proper permissions.", e);
67+
}
68+
}
69+
}
70+
}

DbReflector.Core/Orchestrator.cs

+134-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,140 @@
66

77
namespace DbReflector.Core
88
{
9-
class Orchestrator
9+
using System;
10+
using System.Collections.Generic;
11+
using CodeGenerationRoslynTest.Generators;
12+
using Microsoft.Extensions.Hosting;
13+
using Microsoft.Extensions.DependencyInjection;
14+
using DbReflector.Databases;
15+
16+
namespace DbReflector.CLI
1017
{
18+
public class Orchestrator
19+
{
20+
static CommandLineConfiguration Configuration = new CommandLineConfiguration();
21+
22+
private readonly IPostgresMetadataMapper _postgresMetadataMapper;
23+
private readonly ISqlServerMetadataMapper _sqlServerMetadataMapper;
24+
private readonly IProjectLoader _projectLoader;
25+
private readonly IGenerator _entityGenerator;
26+
private readonly IGenerator _mapperGenerator;
27+
28+
public Program(ISqlServerMetadataMapper sqlServerMapper, IPostgresMetadataMapper postgresMapper, IEnumerable<IGenerator> generators, IProjectLoader projectLoader)
29+
{
30+
_sqlServerMetadataMapper = sqlServerMapper;
31+
_postgresMetadataMapper = postgresMapper;
32+
_projectLoader = projectLoader;
33+
34+
foreach (var generator in generators)
35+
{
36+
if (generator.GetType() == typeof(EntityGenerator))
37+
{
38+
_entityGenerator = generator;
39+
}
40+
else if (generator.GetType() == typeof(RepoDbMapperGenerator))
41+
{
42+
_mapperGenerator = generator;
43+
}
44+
}
45+
}
46+
47+
static void InitConfig()
48+
{
49+
//Postgres Config
50+
Configuration = new CommandLineConfiguration
51+
{
52+
//CSharpProjectFilePath = "Your csproj file root here.",
53+
CSharpProjectFilePath = "C:/Users/cjime/Desktop/Professional Projects/LaCarte/LaCarteAPI/NewSolution/RestaurantAdmin/LaCarte.RestaurantAdmin.DataAccess/LaCarte.RestaurantAdmin.DataAccess.csproj",
54+
GenerateRepoDbMapper = true,
55+
DatabaseName = "restaurant-admin",
56+
ConnectionString = "User ID=postgres;Password=123456;Server=localhost;Port=5432;Database=restaurant-admin;",
57+
DatabaseEngine = SupportedDatabases.Postgres,
58+
ForceRecreate = true,
59+
TablesToIgnore = new List<string>() { "VersionInfo" } //Default migrations table for Fluent Migrator.
60+
};
61+
62+
//SQL Server Config
63+
/*Configuration = new CommandLineConfiguration
64+
{
65+
//CSharpProjectFilePath = "Your csproj file root here.",
66+
CSharpProjectFilePath = "C:/Users/cjime/Desktop/Professional Projects/SqlServerSample/SqlServerSample.csproj",
67+
GenerateRepoDbMapper = true,
68+
DatabaseName = "Northwind",
69+
ConnectionString = "Server=localhost;Database=Northwind;Trusted_Connection=True;",
70+
//ConnectionString = "User ID=postgres;Password=123456;Server=localhost;Port=5432;Database=trainme-dev;",
71+
//SupportedDatabase = SupportedDatabases.Postgres,
72+
DatabaseEngine = SupportedDatabases.SqlServer,
73+
ForceRecreate = true,
74+
TablesToIgnore = new List<string>() { "migrations" } //Default migrations table for Fluent Migrator.
75+
};*/
76+
}
77+
78+
static void Main(string[] args)
79+
{
80+
var host = CreateHostBuilder(args).Build();
81+
InitConfig();
82+
host.Services.GetRequiredService<Program>().Run();
83+
}
84+
85+
void Run()
86+
{
87+
try
88+
{
89+
var databaseMetadata = new Database();
90+
var projectMetadata = _projectLoader.GetCSharpProjectMetadata(Configuration.CSharpProjectFilePath);
91+
92+
switch (Configuration.DatabaseEngine)
93+
{
94+
case SupportedDatabases.Postgres:
95+
databaseMetadata = _postgresMetadataMapper.CreateGeneratorModel(Configuration.ConnectionString, Configuration.DatabaseName, Configuration.TablesToIgnore);
96+
break;
97+
case SupportedDatabases.SqlServer:
98+
databaseMetadata = _sqlServerMetadataMapper.CreateGeneratorModel(Configuration.ConnectionString, Configuration.DatabaseName, Configuration.TablesToIgnore);
99+
break;
100+
}
101+
102+
//Entities must always be generated.
103+
_entityGenerator.Generate(Configuration, projectMetadata, databaseMetadata);
104+
105+
if (Configuration.GenerateRepoDbMapper)
106+
_mapperGenerator.Generate(Configuration, projectMetadata, databaseMetadata);
107+
}
108+
catch (CodeGenerationException codeGenException)
109+
{
110+
Console.Out.WriteLine($"Code generation failed. Exception Message: {codeGenException.Message}");
111+
}
112+
catch (ProjectLoadException projectException)
113+
{
114+
Console.Out.WriteLine($"Project loading failed. Exception Message: {projectException.Message}");
115+
}
116+
catch (DatabaseScanningException databaseException)
117+
{
118+
Console.Out.WriteLine($"Database metadata failed to load. Exception Message: {databaseException.Message}");
119+
}
120+
catch (Exception e)
121+
{
122+
Console.Out.WriteLine($"An unknown error has occurred. Exception Message: {e.Message}");
123+
}
124+
125+
Console.Out.WriteLine("Finished process.");
126+
}
127+
128+
private static IHostBuilder CreateHostBuilder(string[] args)
129+
{
130+
return Host.CreateDefaultBuilder(args).ConfigureServices(services =>
131+
{
132+
services.AddTransient<Program>();
133+
services.AddTransient<IDbScanner<PostgresTable, PostgresColumn>>(provider => new PostgresDatabaseScanner(Configuration.ConnectionString));
134+
services.AddTransient<IDbScanner<SqlServerTable, SqlServerColumn>>(provider => new SqlServerDatabaseScanner(Configuration.ConnectionString));
135+
services.AddTransient<IGenerator, EntityGenerator>();
136+
services.AddTransient<IGenerator, RepoDbMapperGenerator>();
137+
services.AddTransient<IPostgresMetadataMapper, PostgresMetadataMapper>();
138+
services.AddTransient<ISqlServerMetadataMapper, SqlServerMetadataMapper>();
139+
services.AddTransient<IProjectLoader, ProjectLoader>();
140+
});
141+
}
142+
}
11143
}
144+
12145
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace DbReflector.Databases.Exceptions
8+
{
9+
public class DatabaseScanningException : Exception
10+
{
11+
public DatabaseScanningException(string message, Exception innerException) : base(message, innerException)
12+
{
13+
14+
}
15+
}
16+
}

DbReflector/DbReflector.csproj

+3-4
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@
88

99
<ItemGroup>
1010
<Compile Remove="Logging\**" />
11+
<Compile Remove="Models\Logging\**" />
1112
<EmbeddedResource Remove="Logging\**" />
13+
<EmbeddedResource Remove="Models\Logging\**" />
1214
<None Remove="Logging\**" />
15+
<None Remove="Models\Logging\**" />
1316
</ItemGroup>
1417

1518
<ItemGroup>
@@ -26,8 +29,4 @@
2629
<PackageReference Include="System.Data.SqlClient" Version="4.8.2" />
2730
</ItemGroup>
2831

29-
<ItemGroup>
30-
<Folder Include="Models\Logging\" />
31-
</ItemGroup>
32-
3332
</Project>

0 commit comments

Comments
 (0)