Skip to content

Commit d6b96a8

Browse files
Add new options for formatting to ScriptGeneratorOptions (#103)
* Add new ScriptGeneratorOption for the number of newlines between statements * Add test for new generator option * Remove space between data type and parameters * Add new generator options * Add tests * implement functionality * bug fix
1 parent 1381d12 commit d6b96a8

File tree

7 files changed

+245
-14
lines changed

7 files changed

+245
-14
lines changed

SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.CheckConstraint.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,12 @@ public override void ExplicitVisit(CheckConstraintDefinition node)
1515

1616
MarkAndPushAlignmentPoint(start);
1717

18-
GenerateConstraintHead(node);
18+
GenerateConstraintHead(node, _options.NewlineFormattedCheckConstraint);
19+
20+
if (_options.NewlineFormattedCheckConstraint)
21+
{
22+
Indent();
23+
}
1924

2025
GenerateKeyword(TSqlTokenType.Check);
2126

SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.CommonPhrases.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -411,8 +411,10 @@ protected void GenerateParameters(ParameterizedDataTypeReference node)
411411
{
412412
if (node.Parameters.Count > 0)
413413
{
414-
GenerateSpace();
415-
GenerateParenthesisedCommaSeparatedList(node.Parameters);
414+
if (_options.SpaceBetweenDataTypeAndParameters) {
415+
GenerateSpace();
416+
}
417+
GenerateParenthesisedCommaSeparatedList(node.Parameters, false, _options.SpaceBetweenParametersInDataType);
416418
}
417419
}
418420

SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.Constraints.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ partial class SqlScriptGeneratorVisitor
2727
new KeywordGenerator(TSqlTokenType.Null),}},
2828
};
2929

30-
protected void GenerateConstraintHead(ConstraintDefinition node)
30+
protected void GenerateConstraintHead(ConstraintDefinition node, bool newline = false)
3131
{
3232
if (node.ConstraintIdentifier != null)
3333
{
3434
GenerateKeyword(TSqlTokenType.Constraint);
3535
GenerateSpaceAndFragmentIfNotNull(node.ConstraintIdentifier);
36-
GenerateSpace();
36+
GenerateNewLineOrSpace(newline);
3737
}
3838
}
3939

SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.IndexDefinition.cs

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ partial class SqlScriptGeneratorVisitor
1111
{
1212
public override void ExplicitVisit(IndexDefinition node)
1313
{
14+
if (_options.NewLineFormattedIndexDefinition)
15+
{
16+
AlignmentPoint start = new AlignmentPoint();
17+
MarkAndPushAlignmentPoint(start);
18+
}
19+
1420
GenerateKeyword(TSqlTokenType.Index);
1521

1622
if (node.Name != null)
@@ -20,7 +26,15 @@ public override void ExplicitVisit(IndexDefinition node)
2026

2127
if (node.Unique)
2228
{
23-
GenerateSpaceAndKeyword(TSqlTokenType.Unique);
29+
if (_options.NewLineFormattedIndexDefinition)
30+
{
31+
NewLineAndIndent();
32+
}
33+
else
34+
{
35+
GenerateSpace();
36+
}
37+
GenerateKeyword(TSqlTokenType.Unique);
2438
}
2539

2640
if (node.IndexType != null)
@@ -56,16 +70,32 @@ public override void ExplicitVisit(IndexDefinition node)
5670

5771
if (node.IncludeColumns.Count > 0)
5872
{
59-
GenerateSpaceAndIdentifier(CodeGenerationSupporter.Include);
73+
if (_options.NewLineFormattedIndexDefinition)
74+
{
75+
NewLineAndIndent();
76+
}
77+
else
78+
{
79+
GenerateSpace();
80+
}
81+
GenerateIdentifier(CodeGenerationSupporter.Include);
6082
GenerateSpace();
6183
GenerateParenthesisedCommaSeparatedList(node.IncludeColumns);
6284
}
6385

6486
if (node.FilterPredicate != null)
6587
{
66-
GenerateSpaceAndKeyword(TSqlTokenType.Where);
67-
GenerateSpaceAndFragmentIfNotNull(node.FilterPredicate);
68-
}
88+
if (_options.NewLineFormattedIndexDefinition)
89+
{
90+
NewLineAndIndent();
91+
}
92+
else
93+
{
94+
GenerateSpace();
95+
}
96+
GenerateKeyword(TSqlTokenType.Where);
97+
GenerateSpaceAndFragmentIfNotNull(node.FilterPredicate);
98+
}
6999

70100
if (node.IndexOptions.Count > 0)
71101
{
@@ -81,6 +111,11 @@ public override void ExplicitVisit(IndexDefinition node)
81111
}
82112

83113
GenerateFileStreamOn(node);
114+
115+
if (_options.NewLineFormattedIndexDefinition)
116+
{
117+
PopAlignmentPoint();
118+
}
84119
}
85120
}
86121
}

SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.Utils.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ protected void GenerateCommaSeparatedList<T>(IList<T> list, Boolean insertNewLin
220220
}
221221

222222
// generate a comma-separated list
223-
protected void GenerateCommaSeparatedList<T>(IList<T> list, bool insertNewLine, bool indent) where T : TSqlFragment
223+
protected void GenerateCommaSeparatedList<T>(IList<T> list, bool insertNewLine, bool indent, bool generateSpaces = true) where T : TSqlFragment
224224
{
225225
GenerateList(list, delegate()
226226
{
@@ -234,7 +234,7 @@ protected void GenerateCommaSeparatedList<T>(IList<T> list, bool insertNewLine,
234234
Indent();
235235
}
236236
}
237-
else
237+
else if (generateSpaces)
238238
{
239239
GenerateSpace();
240240
}
@@ -282,12 +282,12 @@ protected void GenerateParenthesisedCommaSeparatedList<T>(IList<T> list) where T
282282
}
283283

284284
// generate a parenthsised comma-separated list
285-
protected void GenerateParenthesisedCommaSeparatedList<T>(IList<T> list, Boolean alwaysGenerateParenthses) where T : TSqlFragment
285+
protected void GenerateParenthesisedCommaSeparatedList<T>(IList<T> list, Boolean alwaysGenerateParenthses, Boolean generateSpaces = true) where T : TSqlFragment
286286
{
287287
if (list != null && list.Count > 0)
288288
{
289289
GenerateSymbol(TSqlTokenType.LeftParenthesis);
290-
GenerateCommaSeparatedList(list);
290+
GenerateCommaSeparatedList(list, false, false, generateSpaces);
291291
GenerateSymbol(TSqlTokenType.RightParenthesis);
292292
}
293293
else if (alwaysGenerateParenthses)

SqlScriptDom/ScriptDom/SqlServer/Settings/SqlScriptGeneratorOptions.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,18 @@
2828
<Description>IncludeSemiColons_Description</Description>
2929
<Summary>Gets or sets a boolean indicating if a semi colon should be included after each statement</Summary>
3030
</Setting>
31+
<Setting name="NewLineFormattedIndexDefinition" type="bool" default="false">
32+
<Summary>Gets or sets a boolean indicating if index definitions should have UNIQUE, INCLUDE and WHERE on their own line</Summary>
33+
</Setting>
34+
<Setting name="NewlineFormattedCheckConstraint" type="bool" default="false">
35+
<Summary>Gets or sets a boolean indicating if check constraints should have the CHECK part on it's own line</Summary>
36+
</Setting>
37+
<Setting name="SpaceBetweenDataTypeAndParameters" type="bool" default="true">
38+
<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>
39+
</Setting>
40+
<Setting name="SpaceBetweenParametersInDataType" type="bool" default="true">
41+
<Summary>Gets or sets a boolean indicating if a space should be included between parameters in a data type</Summary>
42+
</Setting>
3143
<Setting name="NumNewlinesAfterStatement" type="int" default="1" min="0">
3244
<Summary>Gets or sets the number of newlines to include after each statement</Summary>
3345
</Setting>

Test/SqlDom/ScriptGeneratorTests.cs

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
//------------------------------------------------------------------------------
66

77
using System;
8+
using System.IO;
89
using Microsoft.SqlServer.TransactSql.ScriptDom;
910
using Microsoft.VisualStudio.TestTools.UnitTesting;
1011
using SqlStudio.Tests.AssemblyTools.TestCategory;
@@ -157,5 +158,181 @@ public void TestNewlinesBetweenStatementsGeneratorOption() {
157158
generator.GenerateScript(statements, out sql);
158159
Assert.AreEqual(tableStatementString + Environment.NewLine + Environment.NewLine + tableStatementString, sql);
159160
}
161+
162+
[TestMethod]
163+
[Priority(0)]
164+
[SqlStudioTestCategory(Category.UnitTest)]
165+
public void TestNewLineFormattedIndexDefinitionDefault() {
166+
Assert.AreEqual(false, new SqlScriptGeneratorOptions().NewLineFormattedIndexDefinition);
167+
}
168+
169+
[TestMethod]
170+
[Priority(0)]
171+
[SqlStudioTestCategory(Category.UnitTest)]
172+
public void TestNewlineFormattedCheckConstraintDefault() {
173+
Assert.AreEqual(false, new SqlScriptGeneratorOptions().NewlineFormattedCheckConstraint);
174+
}
175+
176+
[TestMethod]
177+
[Priority(0)]
178+
[SqlStudioTestCategory(Category.UnitTest)]
179+
public void TestSpaceBetweenDataTypeAndParametersDefault() {
180+
Assert.AreEqual(true, new SqlScriptGeneratorOptions().SpaceBetweenDataTypeAndParameters);
181+
}
182+
183+
[TestMethod]
184+
[Priority(0)]
185+
[SqlStudioTestCategory(Category.UnitTest)]
186+
public void TestSpaceBetweenParametersInDataTypeDefault() {
187+
Assert.AreEqual(true, new SqlScriptGeneratorOptions().SpaceBetweenParametersInDataType);
188+
}
189+
190+
[TestMethod]
191+
[Priority(0)]
192+
[SqlStudioTestCategory(Category.UnitTest)]
193+
public void TestSpaceBetweenDataTypeAndParametersWhenFalse() {
194+
var expectedSqlText = @"CREATE TABLE DummyTable (
195+
ColumnName VARCHAR(50)
196+
);";
197+
198+
ParseAndAssertEquality(expectedSqlText, new SqlScriptGeneratorOptions {
199+
SpaceBetweenDataTypeAndParameters = false
200+
});
201+
}
202+
203+
[TestMethod]
204+
[Priority(0)]
205+
[SqlStudioTestCategory(Category.UnitTest)]
206+
public void TestSpaceBetweenDataTypeAndParametersWhenTrue() {
207+
var expectedSqlText = @"CREATE TABLE DummyTable (
208+
ColumnName VARCHAR (50)
209+
);";
210+
211+
ParseAndAssertEquality(expectedSqlText, new SqlScriptGeneratorOptions {
212+
SpaceBetweenDataTypeAndParameters = true
213+
});
214+
}
215+
216+
[TestMethod]
217+
[Priority(0)]
218+
[SqlStudioTestCategory(Category.UnitTest)]
219+
public void TestSpaceBetweenParametersInDataTypeWhenFalse() {
220+
var expectedSqlText = @"CREATE TABLE DummyTable (
221+
ColumnName DECIMAL (5,2)
222+
);";
223+
224+
ParseAndAssertEquality(expectedSqlText, new SqlScriptGeneratorOptions {
225+
SpaceBetweenParametersInDataType = false
226+
});
227+
}
228+
229+
[TestMethod]
230+
[Priority(0)]
231+
[SqlStudioTestCategory(Category.UnitTest)]
232+
public void TestSpaceBetweenParametersInDataTypeWhenTrue() {
233+
var expectedSqlText = @"CREATE TABLE DummyTable (
234+
ColumnName DECIMAL (5, 2)
235+
);";
236+
237+
ParseAndAssertEquality(expectedSqlText, new SqlScriptGeneratorOptions {
238+
SpaceBetweenParametersInDataType = true
239+
});
240+
}
241+
242+
[TestMethod]
243+
[Priority(0)]
244+
[SqlStudioTestCategory(Category.UnitTest)]
245+
public void TestNewlineFormattedCheckConstraintWhenFalse() {
246+
var expectedSqlText = @"CREATE TABLE DummyTable (
247+
CONSTRAINT ComplicatedConstraint CHECK ((Col1 IS NULL
248+
AND (Col2 <> ''
249+
OR Col3 = 0))
250+
OR (Col1 IS NOT NULL
251+
AND ((Col2 = ''
252+
AND Col3 <> 0)
253+
OR (Col4 IN ('', 'ABC', 'JKL', 'XYZ')
254+
AND Col3 < 0
255+
AND (Col5 <> ''
256+
OR Col6 <> '')))))
257+
);";
258+
259+
ParseAndAssertEquality(expectedSqlText, new SqlScriptGeneratorOptions {
260+
NewlineFormattedCheckConstraint = false
261+
});
262+
}
263+
264+
[TestMethod]
265+
[Priority(0)]
266+
[SqlStudioTestCategory(Category.UnitTest)]
267+
public void TestNewlineFormattedCheckConstraintWhenTrue() {
268+
var expectedSqlText = @"CREATE TABLE DummyTable (
269+
CONSTRAINT ComplicatedConstraint
270+
CHECK ((Col1 IS NULL
271+
AND (Col2 <> ''
272+
OR Col3 = 0))
273+
OR (Col1 IS NOT NULL
274+
AND ((Col2 = ''
275+
AND Col3 <> 0)
276+
OR (Col4 IN ('', 'ABC', 'JKL', 'XYZ')
277+
AND Col3 < 0
278+
AND (Col5 <> ''
279+
OR Col6 <> '')))))
280+
);";
281+
282+
ParseAndAssertEquality(expectedSqlText, new SqlScriptGeneratorOptions {
283+
NewlineFormattedCheckConstraint = true
284+
});
285+
}
286+
287+
[TestMethod]
288+
[Priority(0)]
289+
[SqlStudioTestCategory(Category.UnitTest)]
290+
public void TestNewLineFormattedIndexDefinitionWhenFalse() {
291+
var expectedSqlText = @"CREATE TABLE DummyTable (
292+
INDEX ComplicatedIndex UNIQUE (Col1, Col2, Col3) INCLUDE (Col4, Col5, Col6, Col7, Col8) WHERE Col4 = 'AR'
293+
AND Col3 IN ('ABC', 'XYZ')
294+
AND Col5 = 0
295+
AND Col6 = 1
296+
AND Col7 = 0
297+
AND Col8 IS NOT NULL
298+
);";
299+
300+
ParseAndAssertEquality(expectedSqlText, new SqlScriptGeneratorOptions {
301+
NewLineFormattedIndexDefinition = false
302+
});
303+
}
304+
305+
[TestMethod]
306+
[Priority(0)]
307+
[SqlStudioTestCategory(Category.UnitTest)]
308+
public void TestNewLineFormattedIndexDefinitionWhenTrue() {
309+
var expectedSqlText = @"CREATE TABLE DummyTable (
310+
INDEX ComplicatedIndex
311+
UNIQUE (Col1, Col2, Col3)
312+
INCLUDE (Col4, Col5, Col6, Col7, Col8)
313+
WHERE Col4 = 'AR'
314+
AND Col3 IN ('ABC', 'XYZ')
315+
AND Col5 = 0
316+
AND Col6 = 1
317+
AND Col7 = 0
318+
AND Col8 IS NOT NULL
319+
);";
320+
321+
ParseAndAssertEquality(expectedSqlText, new SqlScriptGeneratorOptions {
322+
NewLineFormattedIndexDefinition = true
323+
});
324+
}
325+
326+
void ParseAndAssertEquality(string sqlText, SqlScriptGeneratorOptions generatorOptions) {
327+
var parser = new TSql160Parser(true);
328+
var fragment = parser.ParseStatementList(new StringReader(sqlText), out var errors);
329+
330+
Assert.AreEqual(0, errors.Count);
331+
332+
var generator = new Sql160ScriptGenerator(generatorOptions);
333+
generator.GenerateScript(fragment, out var generatedSqlText);
334+
335+
Assert.AreEqual(sqlText, generatedSqlText);
336+
}
160337
}
161338
}

0 commit comments

Comments
 (0)