Skip to content

Commit

Permalink
Detect existing lowercase table names
Browse files Browse the repository at this point in the history
  • Loading branch information
cocytus committed Oct 1, 2022
1 parent 2051845 commit e0527ad
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 16 deletions.
62 changes: 47 additions & 15 deletions grate/Migration/AnsiSqlDatabase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public abstract class AnsiSqlDatabase : IDatabase
private DbConnection? _adminConnection;
private readonly ISyntax _syntax;

protected bool LowercaseTableNames { get; set; }

private IDictionary<string, string>? _scriptsRunCache;

protected AnsiSqlDatabase(ILogger logger, ISyntax syntax)
Expand All @@ -48,9 +50,9 @@ protected AnsiSqlDatabase(ILogger logger, ISyntax syntax)

public string StatementSeparatorRegex => _syntax.StatementSeparatorRegex;

public string ScriptsRunTable => _syntax.TableWithSchema(SchemaName, "ScriptsRun");
public string ScriptsRunErrorsTable => _syntax.TableWithSchema(SchemaName, "ScriptsRunErrors");
public string VersionTable => _syntax.TableWithSchema(SchemaName, "Version");
public string ScriptsRunTable => _syntax.TableWithSchema(SchemaName, ScriptsRunTableName);
public string ScriptsRunErrorsTable => _syntax.TableWithSchema(SchemaName, ScriptsRunErrorsTableName);
public string VersionTable => _syntax.TableWithSchema(SchemaName, VersionTableName);

public virtual Task InitializeConnections(GrateConfiguration configuration)
{
Expand Down Expand Up @@ -237,13 +239,15 @@ protected async Task WaitUntilDatabaseIsReady()

public async Task RunSupportTasks()
{
LowercaseTableNames = await CheckIfExistingTablesAreLowercase();

await CreateRunSchema();
await CreateScriptsRunTable();
await CreateScriptsRunErrorsTable();
await CreateVersionTable();
await AddStatusColumnToVersionTable();
}

}

private async Task CreateRunSchema()
{
if (SupportsSchemas && !await RunSchemaExists())
Expand Down Expand Up @@ -274,7 +278,7 @@ protected virtual async Task CreateScriptsRunTable()
entry_date {_syntax.TimestampType} NULL,
modified_date {_syntax.TimestampType} NULL,
entered_by {_syntax.VarcharType}(50) NULL
{_syntax.PrimaryKeyConstraint("ScriptsRun", "id")}
{_syntax.PrimaryKeyConstraint(ScriptsRunTableName, "id")}
)";

if (!await ScriptsRunTableExists())
Expand All @@ -297,7 +301,7 @@ protected virtual async Task CreateScriptsRunErrorsTable()
entry_date {_syntax.TimestampType} NULL,
modified_date {_syntax.TimestampType} NULL,
entered_by {_syntax.VarcharType}(50) NULL
{_syntax.PrimaryKeyConstraint("ScriptsRunErrors", "id")}
{_syntax.PrimaryKeyConstraint(ScriptsRunErrorsTableName, "id")}
)";
if (!await ScriptsRunErrorsTableExists())
{
Expand All @@ -315,7 +319,7 @@ protected virtual async Task CreateVersionTable()
entry_date {_syntax.TimestampType} NULL,
modified_date {_syntax.TimestampType} NULL,
entered_by {_syntax.VarcharType}(50) NULL
{_syntax.PrimaryKeyConstraint("Version", "id")}
{_syntax.PrimaryKeyConstraint(VersionTableName, "id")}
)";
if (!await VersionTableExists())
{
Expand All @@ -335,23 +339,39 @@ ALTER TABLE {VersionTable}
}
}

protected async Task<bool> ScriptsRunTableExists() => await TableExists(SchemaName, "ScriptsRun");
protected async Task<bool> ScriptsRunErrorsTableExists() => await TableExists(SchemaName, "ScriptsRunErrors");
public async Task<bool> VersionTableExists() => await TableExists(SchemaName, "Version");
protected async Task<bool> StatusColumnInVersionTableExists() => await ColumnExists(SchemaName, "Version", "status");
protected async Task<bool> ScriptsRunTableExists() => await TableExists(SchemaName, ScriptsRunTableName);
protected async Task<bool> ScriptsRunErrorsTableExists() => await TableExists(SchemaName, ScriptsRunErrorsTableName);
public async Task<bool> VersionTableExists() => await TableExists(SchemaName, VersionTableName);
protected async Task<bool> StatusColumnInVersionTableExists() => await ColumnExists(SchemaName, VersionTableName, "status");

/// <summary>
/// Returns name in db if table exists.
/// </summary>
/// <param name="schemaName"></param>
/// <param name="tableName"></param>
/// <returns></returns>
public async Task<bool> TableExists(string schemaName, string tableName)
{
var fullTableName = SupportsSchemas ? tableName : _syntax.TableWithSchema(schemaName, tableName);
var tableSchema = SupportsSchemas ? schemaName : DatabaseName;

string existsSql = ExistsSql(tableSchema, fullTableName);

var res = await ExecuteScalarAsync<object>(ActiveConnection, existsSql);
var res = await ExecuteScalarAsync<string>(ActiveConnection, existsSql);

return !DBNull.Value.Equals(res) && res is not null;
}

public async Task<string?> GetExistingTableName(string schemaName, string tableName)
{
var fullTableName = SupportsSchemas ? tableName : _syntax.TableWithSchema(schemaName, tableName);
var tableSchema = SupportsSchemas ? schemaName : DatabaseName;

string existsSql = ExistsSql(tableSchema, fullTableName);

return await ExecuteScalarAsync<string?>(ActiveConnection, existsSql);
}

private async Task<bool> ColumnExists(string schemaName, string tableName, string columnName)
{
var fullTableName = SupportsSchemas ? tableName : _syntax.TableWithSchema(schemaName, tableName);
Expand All @@ -366,10 +386,10 @@ private async Task<bool> ColumnExists(string schemaName, string tableName, strin
protected virtual string ExistsSql(string tableSchema, string fullTableName)
{
return $@"
SELECT * FROM information_schema.tables
SELECT table_name FROM information_schema.tables
WHERE
table_schema = '{tableSchema}' AND
table_name = '{fullTableName}'
LOWER(table_name) = LOWER('{fullTableName}')
";
}

Expand Down Expand Up @@ -615,6 +635,12 @@ INSERT INTO {ScriptsRunErrorsTable}
await ExecuteAsync(ActiveConnection, insertSql, scriptRunErrors);
}

private async Task<bool> CheckIfExistingTablesAreLowercase()
{
var tn = await GetExistingTableName(SchemaName, "ScriptsRun");
return tn == "scriptsrun";
}

private static async Task Close(DbConnection? conn)
{
if (conn?.State == ConnectionState.Open)
Expand Down Expand Up @@ -674,4 +700,10 @@ public async ValueTask DisposeAsync()
}

public abstract Task RestoreDatabase(string backupPath);

private string ScriptsRunTableName => TableName("ScriptsRun");
private string VersionTableName => TableName("Version");
private string ScriptsRunErrorsTableName => TableName("ScriptsRunErrors");

public virtual string TableName(string tableName) => LowercaseTableNames ? tableName.ToLowerInvariant() : tableName;
}
2 changes: 1 addition & 1 deletion grate/Migration/OracleDatabase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public OracleDatabase(ILogger<OracleDatabase> logger)

protected override string ExistsSql(string tableSchema, string fullTableName) =>
$@"
SELECT * FROM user_tables
SELECT table_name FROM user_tables
WHERE
lower(table_name) = '{fullTableName.ToLowerInvariant()}'
";
Expand Down

0 comments on commit e0527ad

Please sign in to comment.