This commit is contained in:
2024-08-09 09:23:47 -05:00
parent 9ece56f15c
commit 5876ac0e8a
5 changed files with 289 additions and 30 deletions

120
SqlDatabase.cs Normal file
View File

@@ -0,0 +1,120 @@
using System.Collections.Generic;
using System.Data.OleDb;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace DbMigrate {
public class SqlDatabase {
public string ConnectionString { get; set; }
public string SqlScript { get; set; }
public List<SqlTable> Tables { get; set; } = new List<SqlTable>();
public SqlDatabase() {
}
public void Connect(string connectionString) {
ConnectionString = connectionString;
}
public void LoadSql(string sql) {
SqlScript = sql;
Tables = ParseTablesFromSql(sql).ToList();
}
public void LoadSqlFromFile(string fileName) {
if (!File.Exists(fileName)) {
throw new FileNotFoundException("SQL file '" + fileName + "' was not found and could not be loaded.");
}
string sql = File.ReadAllText(fileName);
LoadSql(sql);
}
public IEnumerable<SqlTable> ParseTablesFromSql(string sql) {
SqlTable table = null;
StringBuilder sb = new StringBuilder();
foreach (string line in Regex.Split(sql, "\\r\\n")) {
if (string.IsNullOrEmpty(line) || line.StartsWith("--")) {
continue;
}
if (line.ToUpper().StartsWith("CREATE TABLE ")) {
if (table != null) {
table.ParseSql(sb.ToString());
yield return table;
}
// Start a new table
table = new SqlTable();
sb = new StringBuilder();
sb.AppendLine(line);
continue;
}
sb.AppendLine(line);
}
table.ParseSql(sb.ToString());
yield return table;
}
public async Task<string> BuildSql(string dbConnectionString, bool includeIfNotExist = false) {
using (OleDbConnection cn = new OleDbConnection(dbConnectionString)) {
string sql = "";
//List<string> TableSql = new List<string>();
IEnumerable<SqliteTableDefinition> TableDefs = await cn.QueryAsync<SqliteTableDefinition>("select * from sqlite_master");
foreach (SqliteTableDefinition table in TableDefs.Where(f => f.type == "table").OrderBy(f => f.tbl_name)) {
if (table.tbl_name == "sqlite_sequence") { continue; }
Match m = Regex.Match(table.sql, "CREATE TABLE \\S+ \\((.*)\\)", RegexOptions.Singleline);
if (!m.Success) {
Trace.TraceWarning("Unable to match regex on table " + table.name);
continue;
}
int startIndex = m.Groups[1].Index;
int length = m.Groups[1].Length;
string columns = Regex.Replace(m.Groups[1].Value, "\\s{2,}", " ");
columns = Regex.Replace(columns.Replace(", ", ",").Replace(",\n", ","), ",(?!\\d+\\))", ",\r\n\t");
sql += "-- BEGIN TABLE " + table.tbl_name + " --\r\n";
sql += table.sql.Substring(0, startIndex) + "\r\n\t" +
columns.Trim() + "\r\n" +
table.sql.Substring(startIndex + length) + ";\r\n";
List<SqliteTableDefinition> indexes = TableDefs.Where(f => f.type == "index" && f.tbl_name == table.tbl_name && !string.IsNullOrEmpty(f.sql)).ToList();
if (indexes.Count > 0) {
sql += "\r\n-- INDEXES --\r\n";
foreach (var index in indexes) {
if (string.IsNullOrEmpty(index.sql)) { continue; }
sql += index.sql + ";\r\n";
}
}
List<SqliteTableDefinition> triggers = TableDefs.Where(f => f.type == "trigger" && f.tbl_name == table.tbl_name && !string.IsNullOrEmpty(f.sql)).ToList();
if (triggers.Count > 0) {
sql += "\r\n-- TRIGGERS --\r\n";
foreach (var trigger in triggers) {
if (string.IsNullOrEmpty(trigger.sql)) { continue; }
sql += trigger.sql + ";\r\n";
}
}
sql += "-- END TABLE " + table.tbl_name + " --\r\n\r\n";
//TableSql.Add(sql);
}
return sql;
}
}
}
}