Skip to content

Commit

Permalink
Try convert db json string to token
Browse files Browse the repository at this point in the history
  • Loading branch information
Victor Qu authored and Victor Qu committed Oct 17, 2024
1 parent 27da0cb commit 5f0d5f4
Show file tree
Hide file tree
Showing 10 changed files with 358 additions and 51 deletions.
2 changes: 1 addition & 1 deletion ProjectCommon.targets
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VersionSuffix>$(VersionSuffix)</VersionSuffix>
<Version>0.0.2.8</Version>
<Version>0.0.2.9</Version>
<AssemblyVersion>$(Version)</AssemblyVersion>
<FileVersion>$(Version)</FileVersion>
<Version Condition=" '$(VersionSuffix)' != '' ">$(Version)$(VersionSuffix)</Version>
Expand Down
92 changes: 80 additions & 12 deletions src/SV.Db.Sloth.MSSql/ConnectionProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public PageResult<T> ExecuteQuery<T>(string connectionString, DbEntityInfo info,
{
using var connection = Create(connectionString);
var cmd = connection.CreateCommand();
BuildSelectStatement(cmd, info, statement, out var hasTotal, out var hasRows);
var jsonFields = BuildSelectStatement(cmd, info, statement, out var hasTotal, out var hasRows);
if (connection.State != ConnectionState.Open)
{
connection.Open();
Expand All @@ -25,7 +25,33 @@ public PageResult<T> ExecuteQuery<T>(string connectionString, DbEntityInfo info,
}
if (hasRows)
{
result.Rows = reader.Query<T>().AsList();
if (jsonFields != null && typeof(T) == typeof(object))
{
result.Rows = reader.Query<T>().Select(i =>
{
if (i is IDictionary<string, object?> dict)
{
foreach (var item in jsonFields)
{
if (dict.ContainsKey(item) && dict[item] is string str && !string.IsNullOrWhiteSpace(str))
{
try
{
dict[item] = ConnectionFactory.ParseJsonToken(str);
}
catch (Exception)
{
}
}
}
}
return i;
}).AsList();
}
else
{
result.Rows = reader.Query<T>().AsList();
}
}
return result;
}
Expand All @@ -34,7 +60,7 @@ public async Task<PageResult<T>> ExecuteQueryAsync<T>(string connectionString, D
{
using var connection = Create(connectionString);
var cmd = connection.CreateCommand();
BuildSelectStatement(cmd, info, statement, out var hasTotal, out var hasRows);
var jsonFields = BuildSelectStatement(cmd, info, statement, out var hasTotal, out var hasRows);
using var reader = await CommandExtensions.DbDataReaderAsync(cmd, CommandBehavior.CloseConnection, cancellationToken);
var result = new PageResult<T>();
if (hasTotal)
Expand All @@ -43,15 +69,42 @@ public async Task<PageResult<T>> ExecuteQueryAsync<T>(string connectionString, D
}
if (hasRows)
{
result.Rows = await reader.QueryAsync<T>(cancellationToken).ToListAsync(cancellationToken);
if (jsonFields != null && typeof(T) == typeof(object))
{
result.Rows = await reader.QueryAsync<T>(cancellationToken).ToListAsync(i =>
{
if (i is IDictionary<string, object?> dict)
{
foreach (var item in jsonFields)
{
if (dict.ContainsKey(item) && dict[item] is string str && !string.IsNullOrWhiteSpace(str))
{
try
{
dict[item] = ConnectionFactory.ParseJsonToken(str);
}
catch (Exception)
{
}
}
}
}
return i;
}, cancellationToken);
}
else
{
result.Rows = await reader.QueryAsync<T>(cancellationToken).ToListAsync(cancellationToken);
}
}
return result;
}

private void BuildSelectStatement(DbCommand cmd, DbEntityInfo info, SelectStatement statement, out bool hasTotalCount, out bool hasRows)
private ISet<string> BuildSelectStatement(DbCommand cmd, DbEntityInfo info, SelectStatement statement, out bool hasTotalCount, out bool hasRows)
{
cmd.CommandTimeout = info.Timeout;
var fs = statement.Fields;
ISet<string> jf = null;

string table = info.Table;
if (!table.Contains("{Where}", StringComparison.OrdinalIgnoreCase))
Expand Down Expand Up @@ -104,13 +157,15 @@ private void BuildSelectStatement(DbCommand cmd, DbEntityInfo info, SelectStatem

if (hasRows)
{
jf = info.GetJsonFields();
if (fs?.Any(i => i is FieldStatement f && f.Field.Equals("*")) == true)
{
table = table.Replace("{Fields}", info.SelectAll((x, y) => $"{y} as {x}", ","), StringComparison.OrdinalIgnoreCase);
}
else
{
table = table.Replace("{Fields}", ConvertFields(info, fs, true, ParseType.SelectField), StringComparison.OrdinalIgnoreCase);
jf = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
table = table.Replace("{Fields}", ConvertFields(info, fs, true, ParseType.SelectField, jf), StringComparison.OrdinalIgnoreCase);
}
}

Expand All @@ -125,7 +180,7 @@ private void BuildSelectStatement(DbCommand cmd, DbEntityInfo info, SelectStatem

if (statement.GroupBy.IsNotNullOrEmpty())
{
table = table.Replace("{OrderBy}", $"group by {ConvertFields(info, statement.GroupBy, false, ParseType.OrderByField)} ");
table = table.Replace("{OrderBy}", $"group by {ConvertFields(info, statement.GroupBy, false, ParseType.OrderByField, null)} ");
}
else
{
Expand All @@ -135,7 +190,7 @@ private void BuildSelectStatement(DbCommand cmd, DbEntityInfo info, SelectStatem
}
else
{
table = table.Replace("{OrderBy}", " order by " + ConvertFields(info, statement.OrderBy, false, ParseType.OrderByField) + " {Limit} ");
table = table.Replace("{OrderBy}", " order by " + ConvertFields(info, statement.OrderBy, false, ParseType.OrderByField, null) + " {Limit} ");
}

if (!statement.Offset.HasValue)
Expand All @@ -146,9 +201,10 @@ private void BuildSelectStatement(DbCommand cmd, DbEntityInfo info, SelectStatem
}

cmd.CommandText = table;
return jf;
}

private string? ConvertFields(DbEntityInfo info, IEnumerable<FieldStatement>? fs, bool allowAs, ParseType parseType)
private string? ConvertFields(DbEntityInfo info, IEnumerable<FieldStatement>? fs, bool allowAs, ParseType parseType, ISet<string> jsonFields)
{
var sb = new StringBuilder();
var notFirst = false;
Expand All @@ -162,12 +218,12 @@ private void BuildSelectStatement(DbCommand cmd, DbEntityInfo info, SelectStatem
{
notFirst = true;
}
ConvertField(item, info, sb, allowAs, parseType);
ConvertField(item, info, sb, allowAs, parseType, jsonFields);
}
return sb.ToString();
}

private static bool ConvertField(Statement v, DbEntityInfo info, StringBuilder sb, bool allowAs, ParseType parseType)
private static bool ConvertField(Statement v, DbEntityInfo info, StringBuilder sb, bool allowAs, ParseType parseType, ISet<string> jsonFields)
{
var fs = parseType switch
{
Expand All @@ -178,6 +234,10 @@ private static bool ConvertField(Statement v, DbEntityInfo info, StringBuilder s
if (v is JsonFieldStatement js)
{
ConvertJsonField(v, sb, allowAs, fs, js);
if (jsonFields != null && parseType == ParseType.SelectField && !string.IsNullOrWhiteSpace(js.As) && !jsonFields.Contains(js.As))
{
jsonFields.Add(js.As);
}
return true;
}
else if (v is GroupByFuncFieldStatement g)
Expand Down Expand Up @@ -206,6 +266,14 @@ private static bool ConvertField(Statement v, DbEntityInfo info, StringBuilder s
sb.Append(" ");
sb.Append(Enums<OrderByDirection>.GetName(orderBy.Direction));
}
if (jsonFields != null && parseType == ParseType.SelectField && !jsonFields.Contains(f.Field))
{
var all = info.GetJsonFields();
if (all != null && all.Contains(f.Field))
{
jsonFields.Add(f.Field);
}
}
return true;
}
return false;
Expand Down Expand Up @@ -417,7 +485,7 @@ private static void BuildOperaterStatementStr(StringBuilder sb, OperaterStatemen

private static void BuildValueStatement(ValueStatement v, StringBuilder sb, DbCommand cmd, DbEntityInfo info, FieldStatement? fieldValueStatement, BuildConditionContext context, ParseType parseType)
{
if (ConvertField(v, info, sb, false, parseType))
if (ConvertField(v, info, sb, false, parseType, null))
{
}
else if (v is StringValueStatement s)
Expand Down
92 changes: 80 additions & 12 deletions src/SV.Db.Sloth.MySql/ConnectionProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public PageResult<T> ExecuteQuery<T>(string connectionString, DbEntityInfo info,
{
using var connection = Create(connectionString);
var cmd = connection.CreateCommand();
BuildSelectStatement(cmd, info, statement, out var hasTotal, out var hasRows);
var jsonFields = BuildSelectStatement(cmd, info, statement, out var hasTotal, out var hasRows);
if (connection.State != ConnectionState.Open)
{
connection.Open();
Expand All @@ -25,7 +25,33 @@ public PageResult<T> ExecuteQuery<T>(string connectionString, DbEntityInfo info,
}
if (hasRows)
{
result.Rows = reader.Query<T>().AsList();
if (jsonFields != null && typeof(T) == typeof(object))
{
result.Rows = reader.Query<T>().Select(i =>
{
if (i is IDictionary<string, object?> dict)
{
foreach (var item in jsonFields)
{
if (dict.ContainsKey(item) && dict[item] is string str && !string.IsNullOrWhiteSpace(str))
{
try
{
dict[item] = ConnectionFactory.ParseJsonToken(str);
}
catch (Exception)
{
}
}
}
}
return i;
}).AsList();
}
else
{
result.Rows = reader.Query<T>().AsList();
}
}
return result;
}
Expand All @@ -34,7 +60,7 @@ public async Task<PageResult<T>> ExecuteQueryAsync<T>(string connectionString, D
{
using var connection = Create(connectionString);
var cmd = connection.CreateCommand();
BuildSelectStatement(cmd, info, statement, out var hasTotal, out var hasRows);
var jsonFields = BuildSelectStatement(cmd, info, statement, out var hasTotal, out var hasRows);
using var reader = await CommandExtensions.DbDataReaderAsync(cmd, CommandBehavior.CloseConnection, cancellationToken);
var result = new PageResult<T>();
if (hasTotal)
Expand All @@ -43,15 +69,42 @@ public async Task<PageResult<T>> ExecuteQueryAsync<T>(string connectionString, D
}
if (hasRows)
{
result.Rows = await reader.QueryAsync<T>(cancellationToken).ToListAsync(cancellationToken);
if (jsonFields != null && typeof(T) == typeof(object))
{
result.Rows = await reader.QueryAsync<T>(cancellationToken).ToListAsync(i =>
{
if (i is IDictionary<string, object?> dict)
{
foreach (var item in jsonFields)
{
if (dict.ContainsKey(item) && dict[item] is string str && !string.IsNullOrWhiteSpace(str))
{
try
{
dict[item] = ConnectionFactory.ParseJsonToken(str);
}
catch (Exception)
{
}
}
}
}
return i;
}, cancellationToken);
}
else
{
result.Rows = await reader.QueryAsync<T>(cancellationToken).ToListAsync(cancellationToken);
}
}
return result;
}

private void BuildSelectStatement(DbCommand cmd, DbEntityInfo info, SelectStatement statement, out bool hasTotalCount, out bool hasRows)
private ISet<string> BuildSelectStatement(DbCommand cmd, DbEntityInfo info, SelectStatement statement, out bool hasTotalCount, out bool hasRows)
{
cmd.CommandTimeout = info.Timeout;
var fs = statement.Fields;
ISet<string> jf = null;

string table = info.Table;
if (!table.Contains("{Where}", StringComparison.OrdinalIgnoreCase))
Expand Down Expand Up @@ -104,13 +157,15 @@ private void BuildSelectStatement(DbCommand cmd, DbEntityInfo info, SelectStatem

if (hasRows)
{
jf = info.GetJsonFields();
if (fs?.Any(i => i is FieldStatement f && f.Field.Equals("*")) == true)
{
table = table.Replace("{Fields}", info.SelectAll((x, y) => $"{y} as {x}", ","), StringComparison.OrdinalIgnoreCase);
}
else
{
table = table.Replace("{Fields}", ConvertFields(info, fs, true, ParseType.SelectField), StringComparison.OrdinalIgnoreCase);
jf = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
table = table.Replace("{Fields}", ConvertFields(info, fs, true, ParseType.SelectField, jf), StringComparison.OrdinalIgnoreCase);
}
}

Expand All @@ -125,7 +180,7 @@ private void BuildSelectStatement(DbCommand cmd, DbEntityInfo info, SelectStatem

if (statement.GroupBy.IsNotNullOrEmpty())
{
table = table.Replace("{OrderBy}", $"group by {ConvertFields(info, statement.GroupBy, false, ParseType.OrderByField)} ");
table = table.Replace("{OrderBy}", $"group by {ConvertFields(info, statement.GroupBy, false, ParseType.OrderByField, null)} ");
}
else
{
Expand All @@ -135,7 +190,7 @@ private void BuildSelectStatement(DbCommand cmd, DbEntityInfo info, SelectStatem
}
else
{
table = table.Replace("{OrderBy}", " order by " + ConvertFields(info, statement.OrderBy, false, ParseType.OrderByField) + " {Limit} ");
table = table.Replace("{OrderBy}", " order by " + ConvertFields(info, statement.OrderBy, false, ParseType.OrderByField, null) + " {Limit} ");
}

if (!statement.Offset.HasValue)
Expand All @@ -146,9 +201,10 @@ private void BuildSelectStatement(DbCommand cmd, DbEntityInfo info, SelectStatem
}

cmd.CommandText = table;
return jf;
}

private string? ConvertFields(DbEntityInfo info, IEnumerable<FieldStatement>? fs, bool allowAs, ParseType parseType)
private string? ConvertFields(DbEntityInfo info, IEnumerable<FieldStatement>? fs, bool allowAs, ParseType parseType, ISet<string> jsonFields)
{
var sb = new StringBuilder();
var notFirst = false;
Expand All @@ -162,12 +218,12 @@ private void BuildSelectStatement(DbCommand cmd, DbEntityInfo info, SelectStatem
{
notFirst = true;
}
ConvertField(item, info, sb, allowAs, parseType);
ConvertField(item, info, sb, allowAs, parseType, jsonFields);
}
return sb.ToString();
}

private static bool ConvertField(Statement v, DbEntityInfo info, StringBuilder sb, bool allowAs, ParseType parseType)
private static bool ConvertField(Statement v, DbEntityInfo info, StringBuilder sb, bool allowAs, ParseType parseType, ISet<string> jsonFields)
{
var fs = parseType switch
{
Expand All @@ -178,6 +234,10 @@ private static bool ConvertField(Statement v, DbEntityInfo info, StringBuilder s
if (v is JsonFieldStatement js)
{
ConvertJsonField(v, sb, allowAs, fs, js);
if (jsonFields != null && parseType == ParseType.SelectField && !string.IsNullOrWhiteSpace(js.As) && !jsonFields.Contains(js.As))
{
jsonFields.Add(js.As);
}
return true;
}
else if (v is GroupByFuncFieldStatement g)
Expand Down Expand Up @@ -206,6 +266,14 @@ private static bool ConvertField(Statement v, DbEntityInfo info, StringBuilder s
sb.Append(" ");
sb.Append(Enums<OrderByDirection>.GetName(orderBy.Direction));
}
if (jsonFields != null && parseType == ParseType.SelectField && !jsonFields.Contains(f.Field))
{
var all = info.GetJsonFields();
if (all != null && all.Contains(f.Field))
{
jsonFields.Add(f.Field);
}
}
return true;
}
return false;
Expand Down Expand Up @@ -417,7 +485,7 @@ private static void BuildOperaterStatementStr(StringBuilder sb, OperaterStatemen

private static void BuildValueStatement(ValueStatement v, StringBuilder sb, DbCommand cmd, DbEntityInfo info, FieldStatement? fieldValueStatement, BuildConditionContext context, ParseType parseType)
{
if (ConvertField(v, info, sb, false, parseType))
if (ConvertField(v, info, sb, false, parseType, null))
{
}
else if (v is StringValueStatement s)
Expand Down
Loading

0 comments on commit 5f0d5f4

Please sign in to comment.