diff --git a/SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.CheckConstraint.cs b/SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.CheckConstraint.cs index b794282..07a7bdd 100644 --- a/SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.CheckConstraint.cs +++ b/SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.CheckConstraint.cs @@ -15,7 +15,12 @@ public override void ExplicitVisit(CheckConstraintDefinition node) MarkAndPushAlignmentPoint(start); - GenerateConstraintHead(node); + GenerateConstraintHead(node, _options.NewlineFormattedCheckConstraint); + + if (_options.NewlineFormattedCheckConstraint) + { + Indent(); + } GenerateKeyword(TSqlTokenType.Check); diff --git a/SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.CommonPhrases.cs b/SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.CommonPhrases.cs index 48cbbbf..f552e22 100644 --- a/SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.CommonPhrases.cs +++ b/SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.CommonPhrases.cs @@ -411,8 +411,10 @@ protected void GenerateParameters(ParameterizedDataTypeReference node) { if (node.Parameters.Count > 0) { - GenerateSpace(); - GenerateParenthesisedCommaSeparatedList(node.Parameters); + if (_options.SpaceBetweenDataTypeAndParameters) { + GenerateSpace(); + } + GenerateParenthesisedCommaSeparatedList(node.Parameters, false, _options.SpaceBetweenParametersInDataType); } } diff --git a/SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.Constraints.cs b/SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.Constraints.cs index 5f271fa..d331fae 100644 --- a/SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.Constraints.cs +++ b/SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.Constraints.cs @@ -27,13 +27,13 @@ partial class SqlScriptGeneratorVisitor new KeywordGenerator(TSqlTokenType.Null),}}, }; - protected void GenerateConstraintHead(ConstraintDefinition node) + protected void GenerateConstraintHead(ConstraintDefinition node, bool newline = false) { if (node.ConstraintIdentifier != null) { GenerateKeyword(TSqlTokenType.Constraint); GenerateSpaceAndFragmentIfNotNull(node.ConstraintIdentifier); - GenerateSpace(); + GenerateNewLineOrSpace(newline); } } diff --git a/SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.IndexDefinition.cs b/SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.IndexDefinition.cs index 38cc30b..14fbf57 100644 --- a/SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.IndexDefinition.cs +++ b/SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.IndexDefinition.cs @@ -11,6 +11,12 @@ partial class SqlScriptGeneratorVisitor { public override void ExplicitVisit(IndexDefinition node) { + if (_options.NewLineFormattedIndexDefinition) + { + AlignmentPoint start = new AlignmentPoint(); + MarkAndPushAlignmentPoint(start); + } + GenerateKeyword(TSqlTokenType.Index); if (node.Name != null) @@ -20,7 +26,15 @@ public override void ExplicitVisit(IndexDefinition node) if (node.Unique) { - GenerateSpaceAndKeyword(TSqlTokenType.Unique); + if (_options.NewLineFormattedIndexDefinition) + { + NewLineAndIndent(); + } + else + { + GenerateSpace(); + } + GenerateKeyword(TSqlTokenType.Unique); } if (node.IndexType != null) @@ -56,16 +70,32 @@ public override void ExplicitVisit(IndexDefinition node) if (node.IncludeColumns.Count > 0) { - GenerateSpaceAndIdentifier(CodeGenerationSupporter.Include); + if (_options.NewLineFormattedIndexDefinition) + { + NewLineAndIndent(); + } + else + { + GenerateSpace(); + } + GenerateIdentifier(CodeGenerationSupporter.Include); GenerateSpace(); GenerateParenthesisedCommaSeparatedList(node.IncludeColumns); } if (node.FilterPredicate != null) { - GenerateSpaceAndKeyword(TSqlTokenType.Where); - GenerateSpaceAndFragmentIfNotNull(node.FilterPredicate); - } + if (_options.NewLineFormattedIndexDefinition) + { + NewLineAndIndent(); + } + else + { + GenerateSpace(); + } + GenerateKeyword(TSqlTokenType.Where); + GenerateSpaceAndFragmentIfNotNull(node.FilterPredicate); + } if (node.IndexOptions.Count > 0) { @@ -81,6 +111,11 @@ public override void ExplicitVisit(IndexDefinition node) } GenerateFileStreamOn(node); + + if (_options.NewLineFormattedIndexDefinition) + { + PopAlignmentPoint(); + } } } } diff --git a/SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.Utils.cs b/SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.Utils.cs index ea70ab3..f646523 100644 --- a/SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.Utils.cs +++ b/SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.Utils.cs @@ -220,7 +220,7 @@ protected void GenerateCommaSeparatedList(IList list, Boolean insertNewLin } // generate a comma-separated list - protected void GenerateCommaSeparatedList(IList list, bool insertNewLine, bool indent) where T : TSqlFragment + protected void GenerateCommaSeparatedList(IList list, bool insertNewLine, bool indent, bool generateSpaces = true) where T : TSqlFragment { GenerateList(list, delegate() { @@ -234,7 +234,7 @@ protected void GenerateCommaSeparatedList(IList list, bool insertNewLine, Indent(); } } - else + else if (generateSpaces) { GenerateSpace(); } @@ -282,12 +282,12 @@ protected void GenerateParenthesisedCommaSeparatedList(IList list) where T } // generate a parenthsised comma-separated list - protected void GenerateParenthesisedCommaSeparatedList(IList list, Boolean alwaysGenerateParenthses) where T : TSqlFragment + protected void GenerateParenthesisedCommaSeparatedList(IList list, Boolean alwaysGenerateParenthses, Boolean generateSpaces = true) where T : TSqlFragment { if (list != null && list.Count > 0) { GenerateSymbol(TSqlTokenType.LeftParenthesis); - GenerateCommaSeparatedList(list); + GenerateCommaSeparatedList(list, false, false, generateSpaces); GenerateSymbol(TSqlTokenType.RightParenthesis); } else if (alwaysGenerateParenthses) diff --git a/SqlScriptDom/ScriptDom/SqlServer/Settings/SqlScriptGeneratorOptions.xml b/SqlScriptDom/ScriptDom/SqlServer/Settings/SqlScriptGeneratorOptions.xml index 1706235..551033a 100644 --- a/SqlScriptDom/ScriptDom/SqlServer/Settings/SqlScriptGeneratorOptions.xml +++ b/SqlScriptDom/ScriptDom/SqlServer/Settings/SqlScriptGeneratorOptions.xml @@ -28,6 +28,18 @@ IncludeSemiColons_Description Gets or sets a boolean indicating if a semi colon should be included after each statement + + Gets or sets a boolean indicating if index definitions should have UNIQUE, INCLUDE and WHERE on their own line + + + Gets or sets a boolean indicating if check constraints should have the CHECK part on it's own line + + + Gets or sets a boolean indicating if a space should be included between the data type and the parameters in a data type definition + + + Gets or sets a boolean indicating if a space should be included between parameters in a data type + Gets or sets the number of newlines to include after each statement diff --git a/Test/SqlDom/ScriptGeneratorTests.cs b/Test/SqlDom/ScriptGeneratorTests.cs index ee21d8b..9a92ce3 100644 --- a/Test/SqlDom/ScriptGeneratorTests.cs +++ b/Test/SqlDom/ScriptGeneratorTests.cs @@ -5,6 +5,7 @@ //------------------------------------------------------------------------------ using System; +using System.IO; using Microsoft.SqlServer.TransactSql.ScriptDom; using Microsoft.VisualStudio.TestTools.UnitTesting; using SqlStudio.Tests.AssemblyTools.TestCategory; @@ -157,5 +158,181 @@ public void TestNewlinesBetweenStatementsGeneratorOption() { generator.GenerateScript(statements, out sql); Assert.AreEqual(tableStatementString + Environment.NewLine + Environment.NewLine + tableStatementString, sql); } + + [TestMethod] + [Priority(0)] + [SqlStudioTestCategory(Category.UnitTest)] + public void TestNewLineFormattedIndexDefinitionDefault() { + Assert.AreEqual(false, new SqlScriptGeneratorOptions().NewLineFormattedIndexDefinition); + } + + [TestMethod] + [Priority(0)] + [SqlStudioTestCategory(Category.UnitTest)] + public void TestNewlineFormattedCheckConstraintDefault() { + Assert.AreEqual(false, new SqlScriptGeneratorOptions().NewlineFormattedCheckConstraint); + } + + [TestMethod] + [Priority(0)] + [SqlStudioTestCategory(Category.UnitTest)] + public void TestSpaceBetweenDataTypeAndParametersDefault() { + Assert.AreEqual(true, new SqlScriptGeneratorOptions().SpaceBetweenDataTypeAndParameters); + } + + [TestMethod] + [Priority(0)] + [SqlStudioTestCategory(Category.UnitTest)] + public void TestSpaceBetweenParametersInDataTypeDefault() { + Assert.AreEqual(true, new SqlScriptGeneratorOptions().SpaceBetweenParametersInDataType); + } + + [TestMethod] + [Priority(0)] + [SqlStudioTestCategory(Category.UnitTest)] + public void TestSpaceBetweenDataTypeAndParametersWhenFalse() { + var expectedSqlText = @"CREATE TABLE DummyTable ( + ColumnName VARCHAR(50) +);"; + + ParseAndAssertEquality(expectedSqlText, new SqlScriptGeneratorOptions { + SpaceBetweenDataTypeAndParameters = false + }); + } + + [TestMethod] + [Priority(0)] + [SqlStudioTestCategory(Category.UnitTest)] + public void TestSpaceBetweenDataTypeAndParametersWhenTrue() { + var expectedSqlText = @"CREATE TABLE DummyTable ( + ColumnName VARCHAR (50) +);"; + + ParseAndAssertEquality(expectedSqlText, new SqlScriptGeneratorOptions { + SpaceBetweenDataTypeAndParameters = true + }); + } + + [TestMethod] + [Priority(0)] + [SqlStudioTestCategory(Category.UnitTest)] + public void TestSpaceBetweenParametersInDataTypeWhenFalse() { + var expectedSqlText = @"CREATE TABLE DummyTable ( + ColumnName DECIMAL (5,2) +);"; + + ParseAndAssertEquality(expectedSqlText, new SqlScriptGeneratorOptions { + SpaceBetweenParametersInDataType = false + }); + } + + [TestMethod] + [Priority(0)] + [SqlStudioTestCategory(Category.UnitTest)] + public void TestSpaceBetweenParametersInDataTypeWhenTrue() { + var expectedSqlText = @"CREATE TABLE DummyTable ( + ColumnName DECIMAL (5, 2) +);"; + + ParseAndAssertEquality(expectedSqlText, new SqlScriptGeneratorOptions { + SpaceBetweenParametersInDataType = true + }); + } + + [TestMethod] + [Priority(0)] + [SqlStudioTestCategory(Category.UnitTest)] + public void TestNewlineFormattedCheckConstraintWhenFalse() { + var expectedSqlText = @"CREATE TABLE DummyTable ( + CONSTRAINT ComplicatedConstraint CHECK ((Col1 IS NULL + AND (Col2 <> '' + OR Col3 = 0)) + OR (Col1 IS NOT NULL + AND ((Col2 = '' + AND Col3 <> 0) + OR (Col4 IN ('', 'ABC', 'JKL', 'XYZ') + AND Col3 < 0 + AND (Col5 <> '' + OR Col6 <> ''))))) +);"; + + ParseAndAssertEquality(expectedSqlText, new SqlScriptGeneratorOptions { + NewlineFormattedCheckConstraint = false + }); + } + + [TestMethod] + [Priority(0)] + [SqlStudioTestCategory(Category.UnitTest)] + public void TestNewlineFormattedCheckConstraintWhenTrue() { + var expectedSqlText = @"CREATE TABLE DummyTable ( + CONSTRAINT ComplicatedConstraint + CHECK ((Col1 IS NULL + AND (Col2 <> '' + OR Col3 = 0)) + OR (Col1 IS NOT NULL + AND ((Col2 = '' + AND Col3 <> 0) + OR (Col4 IN ('', 'ABC', 'JKL', 'XYZ') + AND Col3 < 0 + AND (Col5 <> '' + OR Col6 <> ''))))) +);"; + + ParseAndAssertEquality(expectedSqlText, new SqlScriptGeneratorOptions { + NewlineFormattedCheckConstraint = true + }); + } + + [TestMethod] + [Priority(0)] + [SqlStudioTestCategory(Category.UnitTest)] + public void TestNewLineFormattedIndexDefinitionWhenFalse() { + var expectedSqlText = @"CREATE TABLE DummyTable ( + INDEX ComplicatedIndex UNIQUE (Col1, Col2, Col3) INCLUDE (Col4, Col5, Col6, Col7, Col8) WHERE Col4 = 'AR' + AND Col3 IN ('ABC', 'XYZ') + AND Col5 = 0 + AND Col6 = 1 + AND Col7 = 0 + AND Col8 IS NOT NULL +);"; + + ParseAndAssertEquality(expectedSqlText, new SqlScriptGeneratorOptions { + NewLineFormattedIndexDefinition = false + }); + } + + [TestMethod] + [Priority(0)] + [SqlStudioTestCategory(Category.UnitTest)] + public void TestNewLineFormattedIndexDefinitionWhenTrue() { + var expectedSqlText = @"CREATE TABLE DummyTable ( + INDEX ComplicatedIndex + UNIQUE (Col1, Col2, Col3) + INCLUDE (Col4, Col5, Col6, Col7, Col8) + WHERE Col4 = 'AR' + AND Col3 IN ('ABC', 'XYZ') + AND Col5 = 0 + AND Col6 = 1 + AND Col7 = 0 + AND Col8 IS NOT NULL +);"; + + ParseAndAssertEquality(expectedSqlText, new SqlScriptGeneratorOptions { + NewLineFormattedIndexDefinition = true + }); + } + + void ParseAndAssertEquality(string sqlText, SqlScriptGeneratorOptions generatorOptions) { + var parser = new TSql160Parser(true); + var fragment = parser.ParseStatementList(new StringReader(sqlText), out var errors); + + Assert.AreEqual(0, errors.Count); + + var generator = new Sql160ScriptGenerator(generatorOptions); + generator.GenerateScript(fragment, out var generatedSqlText); + + Assert.AreEqual(sqlText, generatedSqlText); + } } }