Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ await Verify(connection)
// include only tables and views
.SchemaIncludes(DbObjects.Tables | DbObjects.Views);
```
<sup><a href='/src/Tests/Tests.cs#L393-L399' title='Snippet source file'>snippet source</a> | <a href='#snippet-SchemaInclude' title='Start of snippet'>anchor</a></sup>
<sup><a href='/src/Tests/Tests.cs#L423-L429' title='Snippet source file'>snippet source</a> | <a href='#snippet-SchemaInclude' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

Available values:
Expand Down Expand Up @@ -103,7 +103,7 @@ await Verify(connection)
_ => _ is TableViewBase ||
_.Name == "MyTrigger");
```
<sup><a href='/src/Tests/Tests.cs#L418-L426' title='Snippet source file'>snippet source</a> | <a href='#snippet-SchemaFilter' title='Start of snippet'>anchor</a></sup>
<sup><a href='/src/Tests/Tests.cs#L448-L456' title='Snippet source file'>snippet source</a> | <a href='#snippet-SchemaFilter' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->


Expand All @@ -125,7 +125,7 @@ command.CommandText = "select Value from MyTable";
var value = await command.ExecuteScalarAsync();
await Verify(value!);
```
<sup><a href='/src/Tests/Tests.cs#L202-L212' title='Snippet source file'>snippet source</a> | <a href='#snippet-Recording' title='Start of snippet'>anchor</a></sup>
<sup><a href='/src/Tests/Tests.cs#L232-L242' title='Snippet source file'>snippet source</a> | <a href='#snippet-Recording' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

Will result in the following verified file:
Expand Down Expand Up @@ -180,7 +180,7 @@ await Verify(
sqlEntries = entries
});
```
<sup><a href='/src/Tests/Tests.cs#L279-L309' title='Snippet source file'>snippet source</a> | <a href='#snippet-RecordingSpecific' title='Start of snippet'>anchor</a></sup>
<sup><a href='/src/Tests/Tests.cs#L309-L339' title='Snippet source file'>snippet source</a> | <a href='#snippet-RecordingSpecific' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->


Expand Down Expand Up @@ -208,7 +208,7 @@ var sqlErrorsViaType = entries
.Select(_ => _.Data)
.OfType<ErrorEntry>();
```
<sup><a href='/src/Tests/Tests.cs#L335-L354' title='Snippet source file'>snippet source</a> | <a href='#snippet-RecordingReadingResults' title='Start of snippet'>anchor</a></sup>
<sup><a href='/src/Tests/Tests.cs#L365-L384' title='Snippet source file'>snippet source</a> | <a href='#snippet-RecordingReadingResults' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->


Expand Down
2 changes: 1 addition & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<Project>
<PropertyGroup>
<NoWarn>CS1591;CS0649;CS8632;NU1608;NU1109</NoWarn>
<Version>11.2.0</Version>
<Version>11.3.0</Version>
<LangVersion>preview</LangVersion>
<AssemblyVersion>1.0.0</AssemblyVersion>
<PackageTags>SqlServer, Verify</PackageTags>
Expand Down
9 changes: 9 additions & 0 deletions src/Tests/Tests.CommandOrderByMultipleColumns.verified.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
Text:
select Id,
Name
from MyTable
order by Name,
Id,
HasTransaction: false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
Text:
select Id,
Name
from MyTable
order by Name desc,
Id asc,
HasTransaction: false
}
7 changes: 7 additions & 0 deletions src/Tests/Tests.CommandOrderBySingleColumn.verified.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
Text:
select Value
from MyTable
order by Value,
HasTransaction: false
}
30 changes: 30 additions & 0 deletions src/Tests/Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,36 @@ public async Task CommandFull()
await Verify(command);
}

[Test]
public async Task CommandOrderBySingleColumn()
{
var command = new SqlCommand
{
CommandText = "select Value from MyTable order by Value"
};
await Verify(command);
}

[Test]
public async Task CommandOrderByMultipleColumns()
{
var command = new SqlCommand
{
CommandText = "select Id, Name from MyTable order by Name, Id"
};
await Verify(command);
}

[Test]
public async Task CommandOrderByMultipleColumnsDesc()
{
var command = new SqlCommand
{
CommandText = "select Id, Name from MyTable order by Name desc, Id asc"
};
await Verify(command);
}

[Test]
public async Task Exception()
{
Expand Down
55 changes: 55 additions & 0 deletions src/Verify.SqlServer/FormattedScriptGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
class FormattedScriptGenerator
{
readonly Sql170ScriptGenerator generator = new(
new()
{
SqlVersion = SqlVersion.Sql170,
KeywordCasing = KeywordCasing.Lowercase,
IndentationSize = 2,
AlignClauseBodies = true
});

public string GenerateScript(TSqlFragment fragment)
{
generator.GenerateScript(fragment, out var script);

var collector = new OrderByCollector();
fragment.Accept(collector);

foreach (var orderBy in collector.Clauses)
{
if (orderBy.OrderByElements.Count <= 1)
{
continue;
}

var elements = new List<string>(orderBy.OrderByElements.Count);
foreach (var element in orderBy.OrderByElements)
{
generator.GenerateScript(element, out var text);
elements.Add(text);
}

var singleLine = "order by " + string.Join(", ", elements);

var pos = script.IndexOf(singleLine, StringComparison.Ordinal);
if (pos == -1)
{
continue;
}

var lineStart = script.LastIndexOf('\n', pos) + 1;
var indent = new string(' ', pos - lineStart + "order by ".Length);

var multiLine = "order by " + string.Join(",\n" + indent, elements);

#if NET48
script = script.Substring(0, pos) + multiLine + script.Substring(pos + singleLine.Length);
#else
script = string.Concat(script.AsSpan(0, pos), multiLine, script.AsSpan(pos + singleLine.Length));
#endif
}

return script;
}
}
7 changes: 7 additions & 0 deletions src/Verify.SqlServer/OrderByCollector.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class OrderByCollector : TSqlFragmentVisitor
{
public List<OrderByClause> Clauses { get; } = [];

public override void Visit(OrderByClause node) =>
Clauses.Add(node);
}
20 changes: 5 additions & 15 deletions src/Verify.SqlServer/SqlFormatter.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
static class SqlFormatter
{
static readonly FormattedScriptGenerator generator = new();

public static StringBuilder Format(string input)
{
var parser = new TSql170Parser(false);
Expand All @@ -23,24 +25,12 @@ Failed to parse sql.
var visitor = new RemoveSquareBracketVisitor();
fragment.Accept(visitor);

var generator = new Sql170ScriptGenerator(
new()
{
SqlVersion = SqlVersion.Sql170,
KeywordCasing = KeywordCasing.Lowercase,
IndentationSize = 2,
AlignClauseBodies = true
});

var builder = new StringBuilder();
using (var writer = new StringWriter(builder, CultureInfo.InvariantCulture))
{
generator.GenerateScript(fragment, writer);
}
var script = generator.GenerateScript(fragment);

var builder = new StringBuilder(script);
builder.TrimEnd();
// ReSharper disable once UseIndexFromEndExpression
if (builder[builder.Length -1] == ';')
if (builder[builder.Length - 1] == ';')
{
builder.Length--;
}
Expand Down