kreta/Kreta.DataAccess.Migrations/CustomMigration.cs
2024-03-13 00:33:46 +01:00

299 lines
9.9 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml.Linq;
using FluentMigrator;
namespace Kreta.DataAccess.Migrations
{
public abstract class CustomMigration : Migration
{
#region Public methods
public void SchemaUpdateRegisteredSPFN()
{
Execute.Sql("EXEC [dev].[uspSchemaUpdateRegisteredSPFN]");
}
public void RunAllScriptsOnDboAndDev()
{
string migrationsBasePathForDbo = Path.Combine(
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
"DBScripts",
"Database",
"dbo");
string[] devScripts = Directory.GetFiles(
Path.Combine(
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
"DBScripts",
"Database",
"dev"),
"*.sql",
SearchOption.TopDirectoryOnly);
foreach (string devScriptName in devScripts)
{
Execute.Script(devScriptName);
}
string functionsBasePath = Path.Combine(migrationsBasePathForDbo, "Functions");
List<string> sqlFunctionFilesPath = Directory.GetFiles(
functionsBasePath,
"*.sql",
SearchOption.TopDirectoryOnly)
.ToList();
IEnumerable<string> firstFunctions = File.ReadLines(Path.Combine(functionsBasePath, "FunctionOrder.txt"));
string[] sqlStoredProcedureFilesPath = Directory.GetFiles(
Path.Combine(migrationsBasePathForDbo, "Stored procedures"),
"*.sql",
SearchOption.TopDirectoryOnly);
foreach (string functionsFileName in firstFunctions)
{
string functionPath = Path.Combine(functionsBasePath, functionsFileName);
sqlFunctionFilesPath.Remove(functionPath);
Execute.Script(functionPath);
}
foreach (string sqlFunctionFilePath in sqlFunctionFilesPath)
{
Execute.Script(sqlFunctionFilePath);
}
foreach (string sqlStoredProcedureFilePath in sqlStoredProcedureFilesPath)
{
Execute.Script(sqlStoredProcedureFilePath);
}
}
public void RegisterSPFN(params string[] sqlFileNames)
{
if (sqlFileNames.Length == 0)
{
return;
}
bool? isStoredProcedure;
var errorMessages = new List<string>();
Type migrationType = GetType();
MigrationAttribute migrationAttribute = migrationType.GetCustomAttributes(typeof(MigrationAttribute), true).OfType<MigrationAttribute>().Single();
long migrationVersion = migrationAttribute.Version;
string migrationName = migrationType.Name;
string baseDirectory = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "DBScripts", "Database", "dbo");
foreach (string sqlFileName in sqlFileNames)
{
isStoredProcedure = IsStoredProcedure(sqlFileName, errorMessages);
if (isStoredProcedure.HasValue)
{
if (File.Exists(Path.Combine(baseDirectory, isStoredProcedure.Value ? "Stored procedures" : "Functions", $"{sqlFileName}.sql")))
{
Execute.Sql($"EXEC [dev].[uspRegisterSPFN] '{sqlFileName}', {(isStoredProcedure.Value ? 1 : 0)}");
}
else
{
errorMessages.Add($"Ilyen nevű stored procedure vagy function {sqlFileName} nem található a DBScripts mappában!");
WriteErrorToConsole(errorMessages, migrationVersion, migrationName);
}
}
else
{
WriteErrorToConsole(errorMessages, migrationVersion, migrationName);
}
}
}
public void ExecuteScripts(params string[] sqlFileNames)
{
if (sqlFileNames.Length == 0)
{
return;
}
Type migrationType = GetType();
MigrationAttribute migrationAttribute = migrationType.GetCustomAttributes(typeof(MigrationAttribute), true).OfType<MigrationAttribute>().Single();
string migrationName = migrationType.Name;
string assemblyDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string baseDirectory = Path.Combine(assemblyDirectory, "Scripts", $"{migrationAttribute.Version}_{migrationName}");
string baseArchiveDirectory = Path.Combine(assemblyDirectory, "Scripts", "Archive", $"{migrationAttribute.Version}_{migrationName}");
foreach (string sqlFileName in sqlFileNames)
{
string sqlFilePath = Path.Combine(baseDirectory, sqlFileName);
if (!File.Exists(sqlFilePath))
{
sqlFilePath = Path.Combine(baseArchiveDirectory, sqlFileName);
}
Execute.Script(sqlFilePath);
}
}
public void CreateSchemaSPFN(params string[] spfnList)
{
if (spfnList.Length == 0)
{
return;
}
Execute.Sql($"EXEC [dev].[uspCreateSchemaSPFN] '{string.Join(",", spfnList)}'");
}
public void DropSchemaSPFN(params string[] spfnList)
{
if (spfnList.Length == 0)
{
return;
}
Execute.Sql($"EXEC [dev].[uspDropSchemaSPFN] '{string.Join(",", spfnList)}'");
}
public void CreateSchemaStoredProcedures(params string[] storedProcedureNames)
{
CreateSchemaSPFN(storedProcedureNames);
}
public void CreateSchemaFunctions(params string[] functionNames)
{
CreateSchemaSPFN(functionNames);
}
public void DeleteViews(params string[] viewNames)
{
if (viewNames.Length == 0)
{
return;
}
Execute.Sql($"EXEC [dev].[uspDropSchemaViews] '{string.Join(",", viewNames)}'");
}
public void DeleteStoredProcedures(params string[] storedProcedureNames)
{
DropSchemaSPFN(storedProcedureNames);
}
public void DeleteFunctions(params string[] functionNames)
{
DropSchemaSPFN(functionNames);
}
#endregion
#region Private methods
private bool? IsStoredProcedure(string sqlFileName, List<string> errorMessages)
{
if (sqlFileName.StartsWith("sp_", StringComparison.OrdinalIgnoreCase) || sqlFileName.StartsWith("usp", StringComparison.OrdinalIgnoreCase))
{
return true;
}
if (sqlFileName.StartsWith("fn", StringComparison.OrdinalIgnoreCase))
{
return false;
}
errorMessages.Add($"Nem felel meg az elnevezési konvekcióknak: {sqlFileName}");
return null;
}
private void WriteErrorToConsole(List<string> errorMessages, long migrationVersion, string migrationName)
{
if (errorMessages.Any())
{
//Execute.Sql($"DELETE FROM [dbo].[VersionInfo] WHERE Description = 'TESZT'");
throw new Exception($"Hibás migráció: {migrationVersion}_{migrationName}: {errorMessages[0]}");
}
}
private void ManageViews(string action, string[] viewNames)
{
if (viewNames.Length == 0)
{
return;
}
var viewNamesXml = GetViewNamesXml(viewNames);
ExecuteGlobalSql(action, "pViewNames", viewNamesXml);
}
private void ManageStoredProcedures(string action, string[] storedProcedureNames)
{
if (storedProcedureNames.Length == 0)
{
return;
}
var storedProcedureNamesXml = GetStoredProcedureNamesXml(storedProcedureNames);
ExecuteGlobalSql(action, "pStoredProcedureNames", storedProcedureNamesXml);
}
private void ManageFunctions(string action, string[] functionNames)
{
if (functionNames.Length == 0)
{
return;
}
var functionNamesXml = GetFunctionNamesXml(functionNames);
ExecuteGlobalSql(action, "pFunctionNames", functionNamesXml);
}
private void ExecuteGlobalSql(string action, string parameterName, string parameterXml)
{
var sql = new StringBuilder();
sql.AppendLine($"DECLARE @{parameterName} XML = '{parameterXml}'");
sql.AppendLine($"EXEC [dbo].[sp_Global_{action}] NULL, @{parameterName}");
Execute.Sql(sql.ToString());
}
private string GetViewNamesXml(string[] viewNames)
{
return GetXml("ViewNames", "ViewName", viewNames);
}
private string GetStoredProcedureNamesXml(string[] storedProcedureNames)
{
return GetXml("StoredProcedureNames", "StoredProcedureName", storedProcedureNames);
}
private string GetFunctionNamesXml(string[] functionNames)
{
return GetXml("FunctionNames", "FunctionName", functionNames);
}
private string GetXml(string rootNodeName, string childNodeName, string[] contents)
{
var root = new XElement(rootNodeName);
foreach (string content in contents)
{
root.Add(new XElement(childNodeName, content));
}
var xml = new XDocument(root);
return xml.ToString();
}
#endregion
}
}