From 732e4d586129e42d5e3222888b313366c6a4dfdc Mon Sep 17 00:00:00 2001 From: martinjw Date: Thu, 10 Oct 2024 13:04:43 +0200 Subject: [PATCH] #193 If there are check constraints that look like NOT NULL constraints, name the constraint in the ADD COLUMN --- .../SqlGen/MigrationGenerator.cs | 18 +++++++++++- .../UnitTests/MigrationAddColumn.cs | 28 +++++++++++++++++++ .../DatabaseSchemaViewer.csproj | 4 +-- DatabaseSchemaViewer/app.config | 4 +-- DatabaseSchemaViewer/packages.config | 2 +- 5 files changed, 50 insertions(+), 6 deletions(-) diff --git a/DatabaseSchemaReader/SqlGen/MigrationGenerator.cs b/DatabaseSchemaReader/SqlGen/MigrationGenerator.cs index c92ceb0d..0db17fdb 100644 --- a/DatabaseSchemaReader/SqlGen/MigrationGenerator.cs +++ b/DatabaseSchemaReader/SqlGen/MigrationGenerator.cs @@ -65,6 +65,11 @@ public string AddTable(DatabaseTable databaseTable) return tableGenerator.Write().Trim(); } + private string SanitizeExpression(string expression) + { + return expression.Replace("\"", "").Replace("[", "").Replace("]", ""); + } + public virtual string AddColumn(DatabaseTable databaseTable, DatabaseColumn databaseColumn) { var tableGenerator = CreateTableGenerator(databaseTable); @@ -84,10 +89,21 @@ public virtual string AddColumn(DatabaseTable databaseTable, DatabaseColumn data { addColumn += " DEFAULT CURRENT_TIMESTAMP"; } + //is there a named check constraint? + //check constraints don't have columns, so simply try to find the column name in the expression + //column name may be quoted or [bracketed] but so we do a dumb sanitize + var notNullExpression = $"{databaseColumn.Name} IS NOT NULL"; + var nnc = databaseTable.CheckConstraints.FirstOrDefault(cc => + SanitizeExpression(cc.Expression).Equals(notNullExpression, StringComparison.OrdinalIgnoreCase)); + if (nnc != null) + { + addColumn += " CONSTRAINT " + Escape(nnc.Name); + } //make sure the NOT NULL is AFTER the default if (!addColumn.EndsWith(" NOT NULL")) { - addColumn = addColumn.Replace(" NOT NULL ", " ") + " NOT NULL"; + + addColumn = $"{addColumn.Replace(" NOT NULL ", " ")} NOT NULL"; } } return string.Format(CultureInfo.InvariantCulture, diff --git a/DatabaseSchemaReaderTest/SqlGen/Migrations/UnitTests/MigrationAddColumn.cs b/DatabaseSchemaReaderTest/SqlGen/Migrations/UnitTests/MigrationAddColumn.cs index ea7a56be..26f18e28 100644 --- a/DatabaseSchemaReaderTest/SqlGen/Migrations/UnitTests/MigrationAddColumn.cs +++ b/DatabaseSchemaReaderTest/SqlGen/Migrations/UnitTests/MigrationAddColumn.cs @@ -117,6 +117,34 @@ public void TestOracleNoSchema() Assert.IsTrue(sql.StartsWith("ALTER TABLE \"Orders\" ADD \"COUNTRY\" NVARCHAR2 (20)", StringComparison.OrdinalIgnoreCase), "names should be quoted correctly"); } + + [TestMethod] + public void TestOracleWithCheckConstraint() + { + + //arrange + var migration = new DdlGeneratorFactory(SqlType.Oracle).MigrationGenerator(); + migration.EscapeNames = false; + migration.IncludeSchema = false; + + var table = MigrationCommon.CreateTestTable("Orders"); + table.SchemaOwner = "dbo"; + table.CheckConstraints.Add(new DatabaseConstraint + { + Name = "COUNTRY_NN", + ConstraintType = ConstraintType.Check, + Expression = "\"COUNTRY\" IS NOT NULL" + }); + var column = CreateNewColumn(); + column.Nullable = false; + + //act + var sql = migration.AddColumn(table, column); + + //assert + Assert.IsTrue(sql.StartsWith("ALTER TABLE Orders ADD COUNTRY NVARCHAR2 (20) DEFAULT '' CONSTRAINT COUNTRY_NN NOT NULL", StringComparison.OrdinalIgnoreCase), "default constraint added"); + } + [TestMethod] public void TestMySqlWithSchema() { diff --git a/DatabaseSchemaViewer/DatabaseSchemaViewer.csproj b/DatabaseSchemaViewer/DatabaseSchemaViewer.csproj index c3ad5f91..29646e22 100644 --- a/DatabaseSchemaViewer/DatabaseSchemaViewer.csproj +++ b/DatabaseSchemaViewer/DatabaseSchemaViewer.csproj @@ -78,8 +78,8 @@ - - ..\packages\Oracle.ManagedDataAccess.21.14.0\lib\net462\Oracle.ManagedDataAccess.dll + + ..\packages\Oracle.ManagedDataAccess.23.6.0\lib\net472\Oracle.ManagedDataAccess.dll diff --git a/DatabaseSchemaViewer/app.config b/DatabaseSchemaViewer/app.config index 00c05ac3..3ade4d44 100644 --- a/DatabaseSchemaViewer/app.config +++ b/DatabaseSchemaViewer/app.config @@ -65,7 +65,7 @@ + type="Oracle.ManagedDataAccess.Client.OracleClientFactory, Oracle.ManagedDataAccess, Version=4.122.23.1, Culture=neutral, PublicKeyToken=89b483f429c47342"/> @@ -73,7 +73,7 @@ - + diff --git a/DatabaseSchemaViewer/packages.config b/DatabaseSchemaViewer/packages.config index e7ff0e50..5d7f98f5 100644 --- a/DatabaseSchemaViewer/packages.config +++ b/DatabaseSchemaViewer/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file