Skip to content

Commit df651b4

Browse files
committed
db request builder nullable parameters
1 parent b39162b commit df651b4

File tree

5 files changed

+145
-49
lines changed

5 files changed

+145
-49
lines changed

DataCommander/DataCommander.Providers/Query/QueryForm.cs

Lines changed: 71 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
using DataCommander.Providers.Connection;
2222
using DataCommander.Providers.ResultWriter;
2323
using Foundation.Assertions;
24+
using Foundation.Collections;
2425
using Foundation.Collections.ReadOnly;
2526
using Foundation.Configuration;
2627
using Foundation.Core;
@@ -1733,7 +1734,7 @@ private static GetQueryConfigurationResult GetQueryConfiguration(string commandT
17331734
var configuration = commandText.Substring(configurationStart, configurationEnd - configurationStart + 1);
17341735
query = JsonConvert.DeserializeObject<QueryConfiguration.Query>(configuration);
17351736

1736-
var parametersStart = configurationEnd + 4;
1737+
var parametersStart = configurationEnd + 7;
17371738
var parametersEnd = commandText.IndexOf("-- CommandText", parametersStart) - 3;
17381739
if (parametersEnd >= 0)
17391740
{
@@ -1749,44 +1750,81 @@ private static GetQueryConfigurationResult GetQueryConfiguration(string commandT
17491750
return new GetQueryConfigurationResult(succeeded, query, parameters, resultCommandText);
17501751
}
17511752

1752-
private static ReadOnlyList<DbRequestParameter> ToDbQueryParameters(List<Token> tokens)
1753+
private static DbRequestParameter ToDbRequestParameter(List<Token> declaration)
17531754
{
1754-
var declareTokens = tokens.Where(i => i.Type == TokenType.KeyWord && i.Value == "declare").ToList();
1755-
return declareTokens
1756-
.Where(i => i.Index + 2 < tokens.Count)
1757-
.Select(declareToken =>
1755+
var name = declaration[1].Value;
1756+
name = name.Substring(1);
1757+
var dataType = declaration[2].Value;
1758+
if (declaration[3].Value == ".")
1759+
dataType += "." + declaration[4].Value;
1760+
var dataTypeLower = dataType.ToLower();
1761+
SqlDbType sqlDbType;
1762+
var size = 0;
1763+
bool isNullable;
1764+
string csharpValue = null;
1765+
1766+
var sqlDataType = SqlDataTypeArray.SqlDataTypes.FirstOrDefault(i => i.SqlDataTypeName == dataTypeLower);
1767+
if (sqlDataType != null)
1768+
{
1769+
sqlDbType = sqlDataType.SqlDbType;
1770+
if (declaration.Count > 5 && declaration[3].Value == "(" && declaration[5].Value == ")")
17581771
{
1759-
var index = declareToken.Index;
1760-
var name = tokens[index + 1].Value;
1761-
name = name.Substring(1);
1762-
var dataType = tokens[index + 2].Value;
1763-
var dataTypeLower = dataType.ToLower();
1764-
SqlDbType sqlDbType;
1765-
var size = 0;
1766-
string csharpValue = null;
1767-
1768-
var sqlDataType = SqlDataTypeArray.SqlDataTypes.FirstOrDefault(i => i.SqlDataTypeName == dataTypeLower);
1769-
if (sqlDataType != null)
1770-
{
1771-
sqlDbType = sqlDataType.SqlDbType;
1772-
if (tokens.Count > index + 5 && tokens[index + 3].Value == "(" && tokens[index + 5].Value == ")")
1773-
{
1774-
var sizeString = tokens[index + 4].Value;
1775-
if (sizeString.ToLower() == "max")
1776-
size = -1;
1777-
else
1778-
size = int.Parse(sizeString);
1779-
}
1780-
}
1772+
var sizeString = declaration[4].Value;
1773+
if (sizeString.ToLower() == "max")
1774+
size = -1;
17811775
else
1776+
size = int.Parse(sizeString);
1777+
}
1778+
1779+
isNullable = true;
1780+
1781+
for (var i = 0; i < declaration.Count - 6; ++i)
1782+
{
1783+
if (declaration[i].Value == "/" && declaration[i + 1].Value == "*" &&
1784+
declaration[i + 2].Value.ToLower() == "not" && declaration[i + 3].Value.ToLower() == "null" &&
1785+
declaration[i + 4].Value == "*" && declaration[i + 5].Value == "/")
17821786
{
1783-
sqlDbType = SqlDbType.Structured;
1784-
csharpValue = $"query.{name}.Select(i => i.ToSqlDataRecord()).ToReadOnlyList()";
1787+
isNullable = false;
1788+
break;
17851789
}
1790+
}
1791+
}
1792+
else
1793+
{
1794+
sqlDbType = SqlDbType.Structured;
1795+
isNullable = false;
1796+
csharpValue = $"query.{name}.Select(i => i.ToSqlDataRecord()).ToReadOnlyList()";
1797+
}
1798+
1799+
return new DbRequestParameter(name, dataType, sqlDbType, size, isNullable, csharpValue);
1800+
}
1801+
1802+
private static ReadOnlyList<DbRequestParameter> ToDbQueryParameters(List<Token> tokens)
1803+
{
1804+
var declarations = GetDeclarations(tokens);
1805+
return declarations.Select(ToDbRequestParameter).ToReadOnlyList();
1806+
}
1807+
1808+
private static List<List<Token>> GetDeclarations(List<Token> tokens)
1809+
{
1810+
var declarations = new List<List<Token>>();
1811+
List<Token> declaration = null;
1812+
foreach (var token in tokens)
1813+
{
1814+
if (token.Type == TokenType.KeyWord && token.Value.ToLower() == "declare")
1815+
{
1816+
if (declaration != null)
1817+
declarations.Add(declaration);
1818+
1819+
declaration = new List<Token>();
1820+
}
1821+
1822+
declaration.Add(token);
1823+
}
17861824

1787-
return new DbRequestParameter(name, dataType, sqlDbType, size, false, csharpValue);
1788-
})
1789-
.ToReadOnlyList();
1825+
if (declaration != null)
1826+
declarations.Add(declaration);
1827+
return declarations;
17901828
}
17911829

17921830
private void ShowDataTableText(DataTable dataTable)

DataCommander/DataCommander.Providers/Query/TokenIterator.cs

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,16 @@ public Token Next()
6363

6464
break;
6565
}
66+
else if (OperatorsOrPunctuators.Contains(c))
67+
{
68+
startPosition = _index;
69+
value = c.ToString();
70+
endPosition = _index;
71+
token = new Token(_tokenIndex, startPosition, endPosition, _lineIndex,
72+
TokenType.OperatorOrPunctuator, value);
73+
_index++;
74+
break;
75+
}
6676
else if (char.IsLetter(c) || c == '[' || c == '@')
6777
{
6878
startPosition = _index;
@@ -88,16 +98,6 @@ public Token Next()
8898
token = new Token(_tokenIndex, startPosition, endPosition - 1, _lineIndex, TokenType.Digit, value);
8999
break;
90100
}
91-
else if (OperatorsOrPunctuators.Contains(c))
92-
{
93-
startPosition = _index;
94-
value = c.ToString();
95-
endPosition = _index;
96-
token = new Token(_tokenIndex, startPosition, endPosition, _lineIndex,
97-
TokenType.OperatorOrPunctuator, value);
98-
_index++;
99-
break;
100-
}
101101
else if (c == '\r')
102102
{
103103
_lineIndex++;
@@ -122,14 +122,10 @@ private string ReadKeyWord()
122122
while (_index < _length)
123123
{
124124
var c = _text[_index];
125-
if (char.IsWhiteSpace(c) || c == ',' || c == '(' || c == ')' || c == '=' || c == '+')
126-
{
125+
if (char.IsWhiteSpace(c) || OperatorsOrPunctuators.Contains(c))
127126
break;
128-
}
129127
else
130-
{
131128
_index++;
132-
}
133129

134130
sb.Append(c);
135131
}

Foundation/.NetStandard-2.0/Data/DbQueryBuilding/DbRequestBuilder.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -621,8 +621,20 @@ private string GetToParametersMethod()
621621
string method;
622622
switch (parameter.SqlDbType)
623623
{
624+
case SqlDbType.Bit:
625+
method = !parameter.IsNullable ? "Add" : "AddNullableBit";
626+
break;
627+
624628
case SqlDbType.Date:
625-
method = "AddDate";
629+
method = !parameter.IsNullable ? "AddDate" : "AddNullableDate";
630+
break;
631+
632+
case SqlDbType.DateTime:
633+
method = !parameter.IsNullable ? "Add" : "AddNullableDateTime";
634+
break;
635+
636+
case SqlDbType.Int:
637+
method = !parameter.IsNullable ? "Add" : "AddNullableInt";
626638
break;
627639

628640
case SqlDbType.VarChar:

Foundation/.NetStandard-2.0/Data/SqlClient/SqlParameterCollectionBuilder.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,30 @@ public void Add(string parameterName, object value)
2020
Add(parameter);
2121
}
2222

23+
public void AddNullableBit(string parameterName, bool? value)
24+
{
25+
var parameter = SqlParameterFactory.CreateNullableBit(parameterName, value);
26+
Add(parameter);
27+
}
28+
29+
public void AddNullableDate(string parameterName, DateTime? value)
30+
{
31+
var parameter = SqlParameterFactory.CreateNullableDate(parameterName, value);
32+
Add(parameter);
33+
}
34+
35+
public void AddNullableDateTime(string parameterName, DateTime? value)
36+
{
37+
var parameter = SqlParameterFactory.CreateNullableDateTime(parameterName, value);
38+
Add(parameter);
39+
}
40+
41+
public void AddNullableInt(string parameterName, int? value)
42+
{
43+
var parameter = SqlParameterFactory.CreateNullableInt(parameterName, value);
44+
Add(parameter);
45+
}
46+
2347
public void Add(string parameterName, SqlDbType sqlDbType, object value)
2448
{
2549
var parameter = SqlParameterFactory.Create(parameterName, sqlDbType, value);

Foundation/.NetStandard-2.0/Data/SqlClient/SqlParameterFactory.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,30 @@ public static SqlParameter Create(string parameterName, SqlDbType sqlDbType, obj
1616
return parameter;
1717
}
1818

19+
public static SqlParameter CreateNullableBit(string parameterName, bool? value)
20+
{
21+
var parameterValue = ToParameterValue(value);
22+
return Create(parameterName, SqlDbType.Bit, parameterValue);
23+
}
24+
25+
public static SqlParameter CreateNullableDate(string parameterName, DateTime? value)
26+
{
27+
var parameterValue = ToParameterValue(value);
28+
return Create(parameterName, SqlDbType.Date, parameterValue);
29+
}
30+
31+
public static SqlParameter CreateNullableDateTime(string parameterName, DateTime? value)
32+
{
33+
var parameterValue = ToParameterValue(value);
34+
return Create(parameterName, SqlDbType.DateTime, parameterValue);
35+
}
36+
37+
public static SqlParameter CreateNullableInt(string parameterName, int? value)
38+
{
39+
var parameterValue = ToParameterValue(value);
40+
return Create(parameterName, SqlDbType.Int, parameterValue);
41+
}
42+
1943
public static SqlParameter CreateChar(string parameterName, int size, string value)
2044
{
2145
var parameterValue = value != null ? (object) value : DBNull.Value;
@@ -51,5 +75,7 @@ public static SqlParameter CreateStructured(string parameterName, string typeNam
5175
}
5276

5377
public static SqlParameter CreateXml(string parameterName, string value) => Create(parameterName, SqlDbType.Xml, value);
78+
79+
private static object ToParameterValue<T>(T? value) where T : struct => value != null ? (object) value.Value : DBNull.Value;
5480
}
5581
}

0 commit comments

Comments
 (0)