Skip to content

Commit

Permalink
Added CLI app
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasBouda committed Jan 25, 2024
1 parent dcc7e00 commit afd5c85
Show file tree
Hide file tree
Showing 19 changed files with 329 additions and 206 deletions.
20 changes: 20 additions & 0 deletions src/DbDiagramIo.CLI/DbDiagramIo.CLI.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<ApplicationIcon>flow-diagram.ico</ApplicationIcon>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\DbDiagramIo.MsSql\DbDiagramIo.MsSql.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="CommandLineParser" Version="2.9.1" />
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
</ItemGroup>

</Project>
91 changes: 91 additions & 0 deletions src/DbDiagramIo.CLI/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using CommandLine;
using DbDiagramIo.Core;
using DbDiagramIo.Core.Extensions;
using DbDiagramIo.MsSql;
using Serilog;
using Serilog.Events;

Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.CreateLogger();

Log.Information("DbDiagramIo.CLI v{Version}", Assembly.GetExecutingAssembly().GetName().Version);

Parser.Default.ParseArguments<Options>(args)
.WithParsed(o =>
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Is(o.LogEventLevel)
.WriteTo.Console()
.CreateLogger();

if (!string.IsNullOrEmpty(o.ConnectionString))
{
var schemaReader = new MsSqlSchemaReader(o.ConnectionString);
var schema = schemaReader.GetDbmlSchema();
var dbml = new StringBuilder();

var regexOptions = RegexOptions.IgnoreCase;
var excludedSchemas = o.ExcludedSchemas?.Where(s => !string.IsNullOrEmpty(s)).ToList();
var excludedTables = o.ExcludedTables?.Where(s => !string.IsNullOrEmpty(s)).ToList();

Log.Debug("{Count} tables in total", schema.Tables.Count);

schema.Tables
.Where(t => excludedSchemas.AllSafe(s => !t.Schema.Like(s, regexOptions), true) && excludedTables.AllSafe(s => !t.Name.Like(s, regexOptions), true))
.ToList()
.ForEach(t => dbml.AppendLine(t.ToDbml()));

Log.Debug("{Count} foreign keys in total", schema.ForeignKeys.Count);

schema.ForeignKeys
.Where(f => o.ExcludedSchemas.AllSafe(s => !f.SourceTable.Schema.Like(s, regexOptions), true) && o.ExcludedTables.AllSafe(s => !f.SourceTable.Name.Like(s, regexOptions), true)
&& o.ExcludedSchemas.AllSafe(s => !f.TargetTable.Schema.Like(s, regexOptions), true) && o.ExcludedTables.AllSafe(s => !f.TargetTable.Name.Like(s, regexOptions), true))
.ToList()
.ForEach(t => dbml.AppendLine(t.ToDbml()));

if (!string.IsNullOrEmpty(o.OutputFile))
{
var dirName = Path.GetDirectoryName(o.OutputFile);
if (!string.IsNullOrEmpty(dirName) && !Directory.Exists(dirName))
{
Directory.CreateDirectory(dirName);
}


File.WriteAllText(o.OutputFile, dbml.ToString());

Log.Information("Dbml file created at {OutputFile}", o.OutputFile);
}
else
{
Log.Information("Dbml output:");
Console.WriteLine(dbml.ToString());
}
}
else
{
Log.Error("No connection string provided!");
}
});

public class Options
{
[Option('v', "verbosity", Required = false, HelpText = "Sets the serilog log level.", Default = LogEventLevel.Information)]
public LogEventLevel LogEventLevel { get; set; }

[Option('c', "connection-string", Required = true, HelpText = "The connection string to the database.")]
public string ConnectionString { get; set; } = null!;

[Option("exclude-schemas", Required = false, HelpText = "The schemas to exclude from the dbml output. You can use LIKE syntax here.", Separator = ';')]
public IEnumerable<string>? ExcludedSchemas { get; set; }

[Option("exclude-tables", Required = false, HelpText = "The schemas to exclude from the dbml output. You can use LIKE syntax here e.g. 'AspNet%' to exclude all tables starting with 'AspNet'.", Separator = ';')]
public IEnumerable<string>? ExcludedTables { get; set; }

[Option('o', "output-file", Required = false, HelpText = "The file to write the dbml output to. If not provided, the output will be written to the console.")]
public string? OutputFile { get; set; }
}
Binary file added src/DbDiagramIo.CLI/flow-diagram.ico
Binary file not shown.
11 changes: 11 additions & 0 deletions src/DbDiagramIo.Core/DbDiagramIo.Core.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Serilog" Version="3.1.1" />
</ItemGroup>

</Project>
14 changes: 14 additions & 0 deletions src/DbDiagramIo.Core/EnumerableExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace DbDiagramIo.Core
{
public static class EnumerableExtensions
{
public static bool AllSafe<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate, bool valueIfNull = false)
{
return source?.All(predicate) ?? valueIfNull;
}
}
}
16 changes: 16 additions & 0 deletions src/DbDiagramIo.Core/Extensions/StringExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.Text.RegularExpressions;

namespace DbDiagramIo.Core.Extensions
{
public static class StringExtensions
{
public static bool Like(this string toSearch, string toFind, RegexOptions regexOptions = RegexOptions.None)
{
return new Regex(@"\A" + new Regex(@"\.|\$|\^|\{|\[|\(|\||\)|\*|\+|\?|\\")
.Replace(toFind, ch => @"\" + ch)
.Replace('_', '.')
.Replace("%", ".*") + @"\z", RegexOptions.Singleline | regexOptions)
.IsMatch(toSearch);
}
}
}
35 changes: 26 additions & 9 deletions src/DbDiagramIo.MsSql.sln
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.136
# Visual Studio Version 17
VisualStudioVersion = 17.1.32328.378
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DbDiagramIo.MsSql", "DbDiagramIo.MsSql\DbDiagramIo.MsSql.csproj", "{2B68DE74-9ECE-4A00-8263-0D3E4E608408}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DbDiagramIo.MsSql", "DbDiagramIo.MsSql\DbDiagramIo.MsSql.csproj", "{2B68DE74-9ECE-4A00-8263-0D3E4E608408}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example.DotNetCore", "Example.DotNetCore\Example.DotNetCore.csproj", "{AD3E870C-FD95-4601-8D2A-04B102369D87}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Example.DotNetCore", "Example.DotNetCore\Example.DotNetCore.csproj", "{AD3E870C-FD95-4601-8D2A-04B102369D87}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example.Dotnet461", "Example.Dotnet461\Example.Dotnet461.csproj", "{E417CD4E-4C05-4241-888A-C99D1198DABD}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{416AAB75-36B3-48B2-A43A-FFB7F3928FDC}"
ProjectSection(SolutionItems) = preProject
..\.gitignore = ..\.gitignore
..\README.md = ..\README.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DbDiagramIo.CLI", "DbDiagramIo.CLI\DbDiagramIo.CLI.csproj", "{88EDD710-12DA-4C1F-9F2C-2415835A3402}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{D401BF61-DB8D-4D60-A3A0-E01967458D32}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DbDiagramIo.Core", "DbDiagramIo.Core\DbDiagramIo.Core.csproj", "{75DA610B-BBB1-42AB-A1B7-7BAB7AD57D3B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -23,15 +33,22 @@ Global
{AD3E870C-FD95-4601-8D2A-04B102369D87}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AD3E870C-FD95-4601-8D2A-04B102369D87}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AD3E870C-FD95-4601-8D2A-04B102369D87}.Release|Any CPU.Build.0 = Release|Any CPU
{E417CD4E-4C05-4241-888A-C99D1198DABD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E417CD4E-4C05-4241-888A-C99D1198DABD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E417CD4E-4C05-4241-888A-C99D1198DABD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E417CD4E-4C05-4241-888A-C99D1198DABD}.Release|Any CPU.Build.0 = Release|Any CPU
{88EDD710-12DA-4C1F-9F2C-2415835A3402}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{88EDD710-12DA-4C1F-9F2C-2415835A3402}.Debug|Any CPU.Build.0 = Debug|Any CPU
{88EDD710-12DA-4C1F-9F2C-2415835A3402}.Release|Any CPU.ActiveCfg = Release|Any CPU
{88EDD710-12DA-4C1F-9F2C-2415835A3402}.Release|Any CPU.Build.0 = Release|Any CPU
{75DA610B-BBB1-42AB-A1B7-7BAB7AD57D3B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{75DA610B-BBB1-42AB-A1B7-7BAB7AD57D3B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{75DA610B-BBB1-42AB-A1B7-7BAB7AD57D3B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{75DA610B-BBB1-42AB-A1B7-7BAB7AD57D3B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {72353AAB-C945-4F24-9FBF-41DFABBC3CB2}
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{AD3E870C-FD95-4601-8D2A-04B102369D87} = {D401BF61-DB8D-4D60-A3A0-E01967458D32}
EndGlobalSection
EndGlobal
33 changes: 0 additions & 33 deletions src/DbDiagramIo.MsSql/ColumnDto.cs

This file was deleted.

4 changes: 4 additions & 0 deletions src/DbDiagramIo.MsSql/DbDiagramIo.MsSql.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@
<PackageReference Include="System.Data.SqlClient" Version="4.7.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\DbDiagramIo.Core\DbDiagramIo.Core.csproj" />
</ItemGroup>

</Project>
23 changes: 23 additions & 0 deletions src/DbDiagramIo.MsSql/DbmlSchema.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.Collections.Generic;
using DbDiagramIo.MsSql.Objects;
using DbDiagramIo.MsSql.Objects.Base;

namespace DbDiagramIo.MsSql
{
public class DbmlSchema : IDbmlObject
{
public HashSet<Table> Tables { get; }
public HashSet<ForeignKey> ForeignKeys { get; }

public DbmlSchema(HashSet<Table> tables, HashSet<ForeignKey> foreignKeys)
{
Tables = tables;
ForeignKeys = foreignKeys;
}

public string ToDbml()
{
throw new System.NotImplementedException();
}
}
}
23 changes: 0 additions & 23 deletions src/DbDiagramIo.MsSql/ForeignKeyDto.cs

This file was deleted.

Loading

0 comments on commit afd5c85

Please sign in to comment.