Skip to content

Commit 4bfbdf6

Browse files
author
James Craig
committed
Added better checks for finalizable status (at least for T-SQL).
1 parent ad08efc commit 4bfbdf6

File tree

4 files changed

+79
-5
lines changed

4 files changed

+79
-5
lines changed

src/SQLHelper.DB/HelperClasses/Command.cs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ limitations under the License.
1515
*/
1616

1717
using BigBook;
18+
using SQLHelper.DB.HelperClasses;
1819
using SQLHelper.HelperClasses.Interfaces;
1920
using System;
2021
using System.Collections.Generic;
@@ -41,12 +42,21 @@ public class Command<TCallbackData> : ICommand
4142
/// <param name="callbackObject">Object</param>
4243
public Command(Action<ICommand, IList<dynamic>, TCallbackData> callBack, TCallbackData callbackObject, string sqlCommand, CommandType commandType, IParameter[] parameters)
4344
{
44-
SQLCommand = sqlCommand;
45+
SQLCommand = (sqlCommand ?? "");
4546
CommandType = commandType;
4647
CallBack = callBack ?? ((x, y, z) => { });
4748
Object = callbackObject;
4849
Parameters = parameters ?? new IParameter[0];
49-
Finalizable = (sqlCommand ?? "").ToUpperInvariant().Contains("SELECT");
50+
if (Parameters.Any(x => x.ParameterStarter == "@"))
51+
{
52+
var TempParser = new SelectFinder();
53+
SQLParser.Parser.Parse(SQLCommand, TempParser, SQLParser.Enums.SQLType.TSql);
54+
Finalizable = TempParser.StatementFound;
55+
}
56+
else
57+
{
58+
Finalizable = SQLCommand.ToUpperInvariant().Contains("SELECT");
59+
}
5060
}
5161

5262
/// <summary>
@@ -60,12 +70,21 @@ public Command(Action<ICommand, IList<dynamic>, TCallbackData> callBack, TCallba
6070
/// <param name="callbackObject">Object</param>
6171
public Command(Action<ICommand, IList<dynamic>, TCallbackData> callBack, TCallbackData callbackObject, string sqlCommand, CommandType commandType, string parameterStarter, object[] parameters)
6272
{
63-
SQLCommand = sqlCommand;
73+
SQLCommand = (sqlCommand ?? "");
6474
CommandType = commandType;
6575
Parameters = new List<IParameter>();
6676
CallBack = callBack ?? ((x, y, z) => { });
6777
Object = callbackObject;
68-
Finalizable = (sqlCommand ?? "").ToUpperInvariant().Contains("SELECT");
78+
if (parameterStarter == "@")
79+
{
80+
var TempParser = new SelectFinder();
81+
SQLParser.Parser.Parse(SQLCommand, TempParser, SQLParser.Enums.SQLType.TSql);
82+
Finalizable = TempParser.StatementFound;
83+
}
84+
else
85+
{
86+
Finalizable = SQLCommand.ToUpperInvariant().Contains("SELECT");
87+
}
6988
if (parameters != null)
7089
{
7190
foreach (object CurrentParameter in parameters)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
Copyright 2016 James Craig
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
using Antlr4.Runtime.Misc;
18+
using SQLParser.Parsers.TSql;
19+
20+
namespace SQLHelper.DB.HelperClasses
21+
{
22+
/// <summary>
23+
/// Finds selects within SQL code.
24+
/// </summary>
25+
/// <seealso cref="TSqlParserBaseListener"/>
26+
public class SelectFinder : TSqlParserBaseListener
27+
{
28+
/// <summary>
29+
/// Gets or sets a value indicating whether a select [statement found].
30+
/// </summary>
31+
/// <value><c>true</c> if [statement found]; otherwise, <c>false</c>.</value>
32+
public bool StatementFound { get; set; }
33+
34+
/// <summary>
35+
/// Enter a parse tree produced by <see cref="M:SQLParser.Parsers.TSql.TSqlParser.dml_clause"/>.
36+
/// <para>The default implementation does nothing.</para>
37+
/// </summary>
38+
/// <param name="context">The parse tree.</param>
39+
public override void EnterDml_clause([NotNull] TSqlParser.Dml_clauseContext context)
40+
{
41+
StatementFound |= context.select_statement() != null;
42+
base.EnterDml_clause(context);
43+
}
44+
}
45+
}

src/SQLHelper.DB/SQLHelper.DB.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,11 @@
2727
</PropertyGroup>
2828

2929
<ItemGroup>
30+
<PackageReference Include="SQLParser" Version="1.0.2" />
3031
<PackageReference Include="System.Data.Common" Version="4.3.0" />
3132
<PackageReference Include="System.Data.SqlClient" Version="4.3.1" />
3233
<PackageReference Include="System.Dynamic.Runtime" Version="4.3.0" />
33-
<PackageReference Include="BigBook" Version="1.0.21" />
34+
<PackageReference Include="BigBook" Version="1.0.24" />
3435
<PackageReference Include="Microsoft.Extensions.Configuration" Version="1.1.2" />
3536
<PackageReference Include="Microsoft.CSharp" Version="4.3.0" />
3637
</ItemGroup>

test/SQLHelper.Tests/HelperClasses/CommandTests.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,15 @@ namespace SQLHelper.Tests.HelperClasses
99
{
1010
public class CommandTests
1111
{
12+
[Fact]
13+
public void CanFinalizeIfTest()
14+
{
15+
StringBuilder Builder = new StringBuilder();
16+
var TestItem = new Command<int>((x, y, z) => { Builder.Append(z); }, 10, "IF NOT EXISTS (SELECT * FROM [dbo].[AllReferencesAndID_ManyToManyPropertiesWithCascade] WHERE [dbo].[AllReferencesAndID_ManyToManyPropertiesWithCascade].[AllReferencesAndID_ID_] = 4 AND [dbo].[AllReferencesAndID_ManyToManyPropertiesWithCascade].[ManyToManyPropertiesWithCascade_ID_] = 4) BEGIN INSERT INTO [dbo].[AllReferencesAndID_ManyToManyPropertiesWithCascade]([dbo].[AllReferencesAndID_ManyToManyPropertiesWithCascade].[AllReferencesAndID_ID_],[dbo].[AllReferencesAndID_ManyToManyPropertiesWithCascade].[ManyToManyPropertiesWithCascade_ID_]) VALUES (4,4) END;", CommandType.Text, "@", new object[] { 1, 2, 3 });
17+
Assert.False(TestItem.Finalizable);
18+
TestItem = new Command<int>((x, y, z) => { Builder.Append(z); }, 10, "IF NOT EXISTS (SELECT * FROM [dbo].[AllReferencesAndID_ManyToManyPropertiesWithCascade] WHERE [dbo].[AllReferencesAndID_ManyToManyPropertiesWithCascade].[AllReferencesAndID_ID_] = 4 AND [dbo].[AllReferencesAndID_ManyToManyPropertiesWithCascade].[ManyToManyPropertiesWithCascade_ID_] = 4) BEGIN SELECT * FROM Users END;", CommandType.Text, "@", new object[] { 1, 2, 3 });
19+
}
20+
1221
[Fact]
1322
public void Creation()
1423
{

0 commit comments

Comments
 (0)