107 lines
5.7 KiB
C#
107 lines
5.7 KiB
C#
using DbTools.Model;
|
|
using System.Data;
|
|
using System.Linq;
|
|
using System.Text;
|
|
|
|
namespace DbTools {
|
|
public class Delta {
|
|
|
|
|
|
public string BuildDelta(IDbConnection currentDb, IDbConnection newDb, bool removeUnusedTables = false, bool removeUnusedColumns = false, bool removeUnusedTriggers = true, bool removeUnusedIndexes = true) {
|
|
Database db1 = new Database(currentDb);
|
|
Database db2 = new Database(newDb);
|
|
|
|
return BuildDelta(db1, db2, removeUnusedTables, removeUnusedColumns, removeUnusedTriggers, removeUnusedIndexes);
|
|
}
|
|
|
|
public string BuildDelta(string currentDbSql, string newDbSql, bool removeUnusedTables = false, bool removeUnusedColumns = false, bool removeUnusedTriggers = true, bool removeUnusedIndexes = true) {
|
|
Database db1 = new Database(currentDbSql);
|
|
Database db2 = new Database(newDbSql);
|
|
return BuildDelta(db1, db2, removeUnusedTables, removeUnusedColumns, removeUnusedTriggers, removeUnusedIndexes);
|
|
}
|
|
|
|
public string BuildDelta(IDbConnection currentDb, string newDbSql, bool removeUnusedTables = false, bool removeUnusedColumns = false, bool removeUnusedTriggers = true, bool removeUnusedIndexes = true) {
|
|
Database db1 = new Database(currentDb);
|
|
Database db2 = new Database(newDbSql);
|
|
return BuildDelta(db1, db2, removeUnusedTables, removeUnusedColumns, removeUnusedTriggers, removeUnusedIndexes);
|
|
}
|
|
|
|
public string BuildDelta(string currentDbSql, IDbConnection newDb, bool removeUnusedTables = false, bool removeUnusedColumns = false, bool removeUnusedTriggers = true, bool removeUnusedIndexes = true) {
|
|
Database db1 = new Database(currentDbSql);
|
|
Database db2 = new Database(newDb);
|
|
return BuildDelta(db1, db2, removeUnusedTables, removeUnusedColumns, removeUnusedTriggers, removeUnusedIndexes);
|
|
}
|
|
|
|
private string BuildDelta(Database db1, Database db2, bool removeUnusedTables, bool removeUnusedColumns, bool removeUnusedTriggers, bool removeUnusedIndexes) {
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
// Remove tables that are not in db2 if requested
|
|
if (removeUnusedTables) {
|
|
var unusedTables = db1.Tables.GetTables().Where(t1 => !db2.ContainsTable(t1.TableName)).ToArray();
|
|
if (unusedTables.Length > 0) {
|
|
sb.AppendLine("-- DROP UNUSED TABLES --");
|
|
foreach (var table in unusedTables) {
|
|
sb.AppendLine(table.GenerateDropTable());
|
|
}
|
|
sb.AppendLine();
|
|
}
|
|
}
|
|
|
|
foreach (var table2 in db2.Tables.GetTables()) {
|
|
var table1 = db1.Tables[table2.TableName];
|
|
if (table1 == null) {
|
|
sb.AppendLine(table2.FullSql());
|
|
} else {
|
|
// Remove unused triggers if requested
|
|
if (removeUnusedTriggers) {
|
|
var unusedTriggers = table1.Triggers.Keys.Where(t1 => !table2.Triggers.ContainsKey(t1)).ToArray();
|
|
if (unusedTriggers.Length > 0) {
|
|
sb.AppendLine("-- DROP UNUSED TRIGGERS " + table2.TableName + " --");
|
|
foreach (var trigger in unusedTriggers) {
|
|
sb.AppendLine($"DROP TRIGGER IF EXISTS {trigger};");
|
|
}
|
|
sb.AppendLine();
|
|
}
|
|
}
|
|
|
|
// Remove unused indexes if requested
|
|
if (removeUnusedIndexes) {
|
|
var unusedIndexes = table1.Indexes.Keys.Where(i1 => !table2.Indexes.ContainsKey(i1)).ToArray();
|
|
if (unusedIndexes.Length > 0) {
|
|
sb.AppendLine("-- DROP UNUSED INDEXES IN TABLE " + table2.TableName + " --");
|
|
foreach (var index in unusedIndexes) {
|
|
sb.AppendLine($"DROP INDEX IF EXISTS {index};");
|
|
}
|
|
sb.AppendLine();
|
|
}
|
|
}
|
|
|
|
// Add missing columns
|
|
var commonColumns = table1.GetCommonColumns(table2);
|
|
var onlyInTable2 = table2.Columns.GetColumnNames().Where(c => !commonColumns.Contains(c)).ToArray();
|
|
var onlyInTable1 = table1.Columns.GetColumnNames().Where(c => !commonColumns.Contains(c)).ToArray();
|
|
if (removeUnusedColumns && onlyInTable1.Length > 0) {
|
|
// We have columns in table1 that are not in table2 and we want to remove them,
|
|
// so we need to recreate the table
|
|
sb.AppendLine("-- UNUSED COLUMNS EXIST IN TABLE " + table2.TableName + " --");
|
|
string sql = table2.GenerateTableMigration(table1);
|
|
sb.AppendLine(sql);
|
|
}
|
|
if (onlyInTable2.Length > 0) {
|
|
// We have columns in table2 that are not in table1, so we can just add them
|
|
sb.AppendLine($"-- ALTER TABLE {table2.TableName} --");
|
|
foreach (var colName in onlyInTable2) {
|
|
var col = table2.Columns[colName];
|
|
sb.AppendLine($"ALTER TABLE {table2.TableName} ADD COLUMN {col};");
|
|
}
|
|
sb.AppendLine($"-- END ALTER TABLE {table2.TableName} --");
|
|
sb.AppendLine();
|
|
}
|
|
}
|
|
}
|
|
return sb.ToString();
|
|
}
|
|
|
|
}
|
|
}
|