aboutsummaryrefslogtreecommitdiff
path: root/dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/Migrations/SqliteDatabaseMigrator.cs
diff options
context:
space:
mode:
Diffstat (limited to 'dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/Migrations/SqliteDatabaseMigrator.cs')
-rw-r--r--dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/Migrations/SqliteDatabaseMigrator.cs175
1 files changed, 0 insertions, 175 deletions
diff --git a/dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/Migrations/SqliteDatabaseMigrator.cs b/dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/Migrations/SqliteDatabaseMigrator.cs
deleted file mode 100644
index 33310d6..0000000
--- a/dropped/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/Migrations/SqliteDatabaseMigrator.cs
+++ /dev/null
@@ -1,175 +0,0 @@
-using System.Data;
-using System.Text;
-using System.Text.Json;
-using System.Text.RegularExpressions;
-using Dapper;
-
-namespace CrupestApi.Commons.Crud.Migrations;
-
-public class SqliteDatabaseMigrator : IDatabaseMigrator
-{
- private void CheckTableName(string name)
- {
- if (Regex.Match(name, @"^[_0-9a-zA-Z]+$").Success is false)
- {
- throw new ArgumentException("Fxxk, what have you passed as table name.");
- }
- }
-
- public Table? GetTable(IDbConnection dbConnection, string tableName)
- {
- var count = dbConnection.QuerySingle<int>(
- "SELECT count(*) FROM sqlite_schema WHERE type = 'table' AND name = @TableName;",
- new { TableName = tableName });
- if (count == 0)
- {
- return null;
- }
- else if (count > 1)
- {
- throw new Exception($"More than 1 table has name {tableName}. What happened?");
- }
- else
- {
- var table = new Table(tableName);
- var queryColumns = dbConnection.Query<dynamic>($"PRAGMA table_info({tableName})");
-
- foreach (var column in queryColumns)
- {
- var columnName = (string)column.name;
- var columnType = (string)column.type;
- var isNullable = Convert.ToBoolean(column.notnull);
- var primaryKey = Convert.ToInt32(column.pk);
-
- table.Columns.Add(new TableColumn(columnName, columnType, isNullable, primaryKey));
- }
-
- return table;
- }
- }
-
- public Table ConvertTableInfoToTable(TableInfo tableInfo)
- {
- var table = new Table(tableInfo.TableName);
-
- foreach (var columnInfo in tableInfo.Columns)
- {
- table.Columns.Add(new TableColumn(columnInfo.ColumnName, columnInfo.ColumnType.GetSqlTypeString(),
- columnInfo.IsNotNull, columnInfo.IsPrimaryKey ? 1 : 0));
- }
-
- return table;
- }
-
- public string GenerateCreateTableColumnSqlSegment(TableColumn column)
- {
- StringBuilder result = new StringBuilder();
- result.Append(column.Name);
- result.Append(' ');
- result.Append(column.Type);
- if (column.PrimaryKey is not 0)
- {
- result.Append(" PRIMARY KEY AUTOINCREMENT");
- }
- else if (column.NotNull)
- {
- result.Append(" NOT NULL");
- }
-
- return result.ToString();
- }
-
- public string GenerateCreateTableSql(string tableName, IEnumerable<TableColumn> columns)
- {
- CheckTableName(tableName);
-
- var sql = $@"
-CREATE TABLE {tableName} (
- {string.Join(",\n ", columns.Select(GenerateCreateTableColumnSqlSegment))}
-);
- ".Trim();
-
- return sql;
-
- }
-
- public void AutoMigrate(IDbConnection dbConnection, TableInfo tableInfo)
- {
- var tableName = tableInfo.TableName;
- var databaseTable = GetTable(dbConnection, tableName);
- var wantedTable = ConvertTableInfoToTable(tableInfo);
- var databaseTableColumnNames = databaseTable is null ? new List<string>() : databaseTable.Columns.Select(column => column.Name).ToList();
- var wantedTableColumnNames = wantedTable.Columns.Select(column => column.Name).ToList();
-
- var notChangeColumns = wantedTableColumnNames.Where(column => databaseTableColumnNames.Contains(column)).ToList();
- var addColumns = wantedTableColumnNames.Where(column => !databaseTableColumnNames.Contains(column)).ToList();
-
- if (databaseTable is not null && dbConnection.QuerySingle<int>($"SELECT count(*) FROM {tableName}") > 0)
- {
- foreach (var columnName in addColumns)
- {
- var columnInfo = tableInfo.GetColumn(columnName);
- if (!columnInfo.CanBeGenerated)
- {
- throw new Exception($"Column {columnName} cannot be generated. So we can't auto-migrate.");
- }
- }
- }
-
- // We are sqlite, so it's a little bit difficult.
- using var transaction = dbConnection.BeginTransaction();
-
- if (databaseTable is not null)
- {
- var tempTableName = tableInfo.TableName + "_temp";
- dbConnection.Execute($"ALTER TABLE {tableName} RENAME TO {tempTableName}", new { TableName = tableName, tempTableName });
-
- var createTableSql = GenerateCreateTableSql(tableName, wantedTable.Columns);
- dbConnection.Execute(createTableSql);
-
- // Copy old data to new table.
- var originalRows = dbConnection.Query<dynamic>($"SELECT * FROM {tempTableName}").Cast<IDictionary<string, object?>>().ToList();
- foreach (var originalRow in originalRows)
- {
- var parameters = new DynamicParameters();
-
- foreach (var columnName in notChangeColumns)
- {
- parameters.Add(columnName, originalRow[columnName]);
- }
-
- foreach (var columnName in addColumns)
- {
- parameters.Add(columnName, tableInfo.GetColumn(columnName).GenerateDefaultValue());
- }
-
- string columnSql = string.Join(", ", wantedTableColumnNames);
- string valuesSql = string.Join(", ", wantedTableColumnNames.Select(c => "@" + c));
-
- string sql = $"INSERT INTO {tableName} ({columnSql}) VALUES {valuesSql})";
- dbConnection.Execute(sql, parameters);
- }
-
- // Finally drop old table
- dbConnection.Execute($"DROP TABLE {tempTableName}");
- }
- else
- {
- var createTableSql = GenerateCreateTableSql(tableName, wantedTable.Columns);
- dbConnection.Execute(createTableSql);
- }
-
- // Commit transaction.
- transaction.Commit();
- }
-
- public bool NeedMigrate(IDbConnection dbConnection, TableInfo tableInfo)
- {
- var tableName = tableInfo.TableName;
- var databaseTable = GetTable(dbConnection, tableName);
- var wantedTable = ConvertTableInfoToTable(tableInfo);
- var databaseTableColumns = databaseTable is null ? new HashSet<string>() : new HashSet<string>(databaseTable.Columns.Select(c => c.Name));
- var wantedTableColumns = new HashSet<string>(wantedTable.Columns.Select(c => c.Name));
- return !databaseTableColumns.SetEquals(wantedTableColumns);
- }
-}