Created
February 14, 2022 04:53
-
-
Save Sandip124/454fbd63c623711020269625af2ed209 to your computer and use it in GitHub Desktop.
Sql Splitter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using System.Text; | |
using System.Text.RegularExpressions; | |
using System.Threading.Tasks; | |
namespace SchemaSplitter | |
{ | |
class Program | |
{ | |
public const string FileName = "schema.sql"; | |
public const string OutputDirectoryPath = "output"; | |
static async Task Main(string[] args) | |
{ | |
var fileName = args.Length > 0 && !string.IsNullOrEmpty(args[0]) ? args[0] : FileName; | |
try | |
{ | |
var currentDirectory = Directory.GetCurrentDirectory(); | |
var absolutePath = Path.Combine(currentDirectory, fileName!); | |
var outputDirectory = Path.Combine(currentDirectory, OutputDirectoryPath); | |
CleanDirectory(outputDirectory); | |
if (File.Exists(absolutePath)) | |
{ | |
var fileLine = CleanUpFileForSplitting(fileName); | |
var stringBuilder = new StringBuilder(); | |
foreach (var line in fileLine) | |
{ | |
if (IsComment(line)) continue; | |
if (line.StartsWith("SET SQL_MODE")) continue; | |
stringBuilder.AppendLine(line); | |
var sourceString = stringBuilder.ToString(); | |
var resultFileName = GetFileNameFromSqlStatement(sourceString); | |
var outputDirPath = outputDirectory; | |
resultFileName = GenerateDirectoryAndFileName(sourceString, resultFileName, ref outputDirPath); | |
Console.WriteLine(resultFileName); | |
CreateDirectoryIfNotExists(outputDirPath); | |
await SaveFile(sourceString, outputDirPath, resultFileName); | |
stringBuilder.Clear(); | |
} | |
} | |
} | |
catch (Exception e) | |
{ | |
Console.WriteLine(e); | |
} | |
} | |
private static void CleanDirectory(string outputDirectory) | |
{ | |
Directory.Delete(outputDirectory, true); | |
} | |
private static async Task SaveFile(string sourceString, string dirPath, string resultFileName) | |
{ | |
var path = Path.Combine(dirPath, GetFileNameWithExtension(resultFileName)); | |
if (File.Exists(path)) | |
{ | |
await using var file = File.Open(path, FileMode.Append, FileAccess.Write); | |
await using var writer = new StreamWriter(file); | |
await writer.WriteLineAsync(sourceString); | |
await writer.FlushAsync(); | |
} | |
else | |
{ | |
await using var fs = File.Create(path); | |
var content = new UTF8Encoding(true).GetBytes(sourceString); | |
fs.Write(content, 0, content.Length); | |
} | |
} | |
private static void CreateDirectoryIfNotExists(string dirPath) | |
{ | |
if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath); | |
} | |
private static string GetFileNameWithExtension(string resultFileName,string extension = "sql") | |
{ | |
return $"{resultFileName}.{extension}"; | |
} | |
private static string GenerateDirectoryAndFileName(string sourceString, string resultFileName, ref string dirPath) | |
{ | |
const string schemaPath = "schema"; | |
const string seedPath = "seed"; | |
const string constraintPath = "constraint"; | |
if (sourceString.StartsWith("CREATE TABLE")) | |
{ | |
resultFileName = $"{schemaPath}_{resultFileName}"; | |
dirPath = Path.Combine(dirPath, schemaPath); | |
} | |
else if (sourceString.StartsWith("ALTER TABLE")) | |
{ | |
resultFileName = $"{constraintPath}_{resultFileName}"; | |
dirPath = Path.Combine(dirPath, constraintPath); | |
} | |
else if (sourceString.StartsWith("INSERT INTO")) | |
{ | |
resultFileName = $"{seedPath}_{resultFileName}"; | |
dirPath = Path.Combine(dirPath, seedPath); | |
} | |
return resultFileName; | |
} | |
private static IEnumerable<string> CleanUpFileForSplitting(string fileName) | |
{ | |
var fileLine = File.ReadAllText(fileName); | |
fileLine = fileLine.Replace("START TRANSACTION;",""); | |
fileLine = fileLine.Replace("COMMIT;",""); | |
var multipleLinesCleaned = Regex.Replace(fileLine, @"^\s+$[\n\n]*", "\n", RegexOptions.Multiline); | |
var result = multipleLinesCleaned.Split(new[] { "\n\n" }, | |
StringSplitOptions.RemoveEmptyEntries); | |
return result; | |
} | |
private static string GetFileNameFromSqlStatement(string sourceString, string delimiter = "`") | |
{ | |
var startIndex = sourceString.IndexOf(delimiter, StringComparison.Ordinal) + 1; | |
var secondIndex = sourceString.IndexOf(delimiter, startIndex, StringComparison.Ordinal); | |
var length = secondIndex - startIndex; | |
var resultFileName = sourceString.Substring(startIndex, length); | |
return resultFileName; | |
} | |
private static bool IsComment(string line) | |
{ | |
return line.StartsWith("/*") && line.EndsWith("*/;"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment