Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new options for formatting to ScriptGeneratorOptions #103

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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)
{
Expand All @@ -81,6 +111,11 @@ public override void ExplicitVisit(IndexDefinition node)
}

GenerateFileStreamOn(node);

if (_options.NewLineFormattedIndexDefinition)
{
PopAlignmentPoint();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ protected void GenerateCommaSeparatedList<T>(IList<T> list, Boolean insertNewLin
}

// generate a comma-separated list
protected void GenerateCommaSeparatedList<T>(IList<T> list, bool insertNewLine, bool indent) where T : TSqlFragment
protected void GenerateCommaSeparatedList<T>(IList<T> list, bool insertNewLine, bool indent, bool generateSpaces = true) where T : TSqlFragment
{
GenerateList(list, delegate()
{
Expand All @@ -234,7 +234,7 @@ protected void GenerateCommaSeparatedList<T>(IList<T> list, bool insertNewLine,
Indent();
}
}
else
else if (generateSpaces)
{
GenerateSpace();
}
Expand Down Expand Up @@ -282,12 +282,12 @@ protected void GenerateParenthesisedCommaSeparatedList<T>(IList<T> list) where T
}

// generate a parenthsised comma-separated list
protected void GenerateParenthesisedCommaSeparatedList<T>(IList<T> list, Boolean alwaysGenerateParenthses) where T : TSqlFragment
protected void GenerateParenthesisedCommaSeparatedList<T>(IList<T> 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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,18 @@
<Description>IncludeSemiColons_Description</Description>
<Summary>Gets or sets a boolean indicating if a semi colon should be included after each statement</Summary>
</Setting>
<Setting name="NewLineFormattedIndexDefinition" type="bool" default="false">
<Summary>Gets or sets a boolean indicating if index definitions should have UNIQUE, INCLUDE and WHERE on their own line</Summary>
</Setting>
<Setting name="NewlineFormattedCheckConstraint" type="bool" default="false">
<Summary>Gets or sets a boolean indicating if check constraints should have the CHECK part on it's own line</Summary>
</Setting>
<Setting name="SpaceBetweenDataTypeAndParameters" type="bool" default="true">
<Summary>Gets or sets a boolean indicating if a space should be included between the data type and the parameters in a data type definition</Summary>
</Setting>
<Setting name="SpaceBetweenParametersInDataType" type="bool" default="true">
<Summary>Gets or sets a boolean indicating if a space should be included between parameters in a data type</Summary>
</Setting>
<Setting name="NumNewlinesAfterStatement" type="int" default="1" min="0">
<Summary>Gets or sets the number of newlines to include after each statement</Summary>
</Setting>
Expand Down
177 changes: 177 additions & 0 deletions Test/SqlDom/ScriptGeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
//------------------------------------------------------------------------------

using System;
using System.IO;
using Microsoft.SqlServer.TransactSql.ScriptDom;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SqlStudio.Tests.AssemblyTools.TestCategory;
Expand Down Expand Up @@ -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);
}
}
}
Loading