Skip to content

Commit

Permalink
Merge pull request #79 from VahidFarahmandian/78-version-conflict-det…
Browse files Browse the repository at this point in the history
…ected-for-microsoftcodeanalysiscommon

packages updated
  • Loading branch information
VahidFarahmandian authored Jan 18, 2024
2 parents 00cca97 + 865dcd7 commit bf64292
Show file tree
Hide file tree
Showing 27 changed files with 147 additions and 121 deletions.
15 changes: 6 additions & 9 deletions 01-Core/Jinget.Core/CodeDom/JingetDynamicCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,16 @@ namespace Jinget.Core.CodeDom
{
public sealed class JingetDynamicCode
{
private readonly Compiler _compiler;

public JingetDynamicCode() => _compiler = new Compiler();

private class Compiler
{
/// <param name="errors">Compilation might be ended with some errors. The compile time errors are stored in this output parameter</param>
/// <param name="jingetSource">During the dynamic code execution process, given sourceCode might change. Changed version of the sourceCode are stored in this output parameter</param>
/// <param name="isTopLevelStatement">C# 9.0 enables you to write top level statements.</param>
/// <param name="references">In order to compile the given sourceCode, some external references might needed to be added. Required references are being passed using this parameter</param>
internal byte[]? Compile(string sourceCode, MethodOptions? args, out List<string> errors, out string jingetSource,
internal static byte[]? Compile(string sourceCode, MethodOptions? args, out List<string> errors, out string jingetSource,
bool isTopLevelStatement = true, List<string>? references = null)
{
references ??= [];
jingetSource = string.Empty;
errors = [];

Expand Down Expand Up @@ -63,7 +60,7 @@ private class Compiler
/// <summary>
/// Generaetes new dynamic dll, based on the given source code. this dll created on the fly
/// </summary>
CSharpCompilation GenerateAssembly(string sourceCode, List<string> externalReferences)
static CSharpCompilation GenerateAssembly(string sourceCode, List<string> externalReferences)
{
var codeString = SourceText.From(sourceCode);
var options = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest);
Expand All @@ -80,7 +77,7 @@ CSharpCompilation GenerateAssembly(string sourceCode, List<string> externalRefer
references.AddRange(externalReferences.Distinct().Select(x => MetadataReference.CreateFromFile(x)));

return CSharpCompilation.Create($"{Guid.NewGuid()}.dll",
new[] { parsedSyntaxTree },
[parsedSyntaxTree],
references: references,
options: new CSharpCompilationOptions(
OutputKind.DynamicallyLinkedLibrary,
Expand Down Expand Up @@ -169,14 +166,14 @@ static string GenerateSourceCode(string expression, MethodOptions? methodOptions
}

[MethodImpl(MethodImplOptions.NoInlining)]
public object? Execute(string sourceCode, out List<string> errors, out string compiledSourceCode, MethodOptions? options = null, bool isTopLevelStatement = true, bool compileOnly = false, List<string>? references = null)
public static object? Execute(string sourceCode, out List<string> errors, out string compiledSourceCode, MethodOptions? options = null, bool isTopLevelStatement = true, bool compileOnly = false, List<string>? references = null)
{
if (sourceCode.Length > 10000)
{
throw new ArgumentException("Jinget says: sourceCode is too long. sourceCode max length is 10000 characters");
}

var compiledCode = _compiler.Compile(sourceCode, options, out errors, out compiledSourceCode,
var compiledCode = Compiler.Compile(sourceCode, options, out errors, out compiledSourceCode,
isTopLevelStatement, references);
if (compiledCode is null || compileOnly)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
/// <summary>
/// add support for 'required' keyword using latest lang version and .net standard 2.1
/// </summary>
#pragma warning disable CA1018 // Mark attributes with AttributeUsageAttribute
public class CompilerFeatureRequiredAttribute(string name) : Attribute

Check warning on line 7 in 01-Core/Jinget.Core/Compiler/CompilerFeatureRequiredAttribute.cs

View workflow job for this annotation

GitHub Actions / build

Parameter 'name' is unread.

Check warning on line 7 in 01-Core/Jinget.Core/Compiler/CompilerFeatureRequiredAttribute.cs

View workflow job for this annotation

GitHub Actions / releasePreview

Parameter 'name' is unread.
#pragma warning restore CA1018 // Mark attributes with AttributeUsageAttribute
{
}
6 changes: 3 additions & 3 deletions 01-Core/Jinget.Core/ExpressionToSql/Internal/Query.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ namespace Jinget.Core.ExpressionToSql.Internal
{
public abstract class Query
{
public (QueryBuilder query, Dictionary<string, object>? parameters) ToSql() => ToSql(new StringBuilder());
public (QueryBuilder query, Dictionary<string, object?>? parameters) ToSql() => ToSql(new StringBuilder());

private (QueryBuilder query, Dictionary<string, object>? parameters) ToSql(StringBuilder sb)
private (QueryBuilder query, Dictionary<string, object?>? parameters) ToSql(StringBuilder sb)
{
var (query, parameters) = ToSql(new QueryBuilder(sb));
return (query, parameters);
}

internal abstract (QueryBuilder query, Dictionary<string, object>? parameters) ToSql(QueryBuilder query);
internal abstract (QueryBuilder query, Dictionary<string, object?>? parameters) ToSql(QueryBuilder query);
}
}
24 changes: 20 additions & 4 deletions 01-Core/Jinget.Core/ExpressionToSql/Internal/QueryBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ public QueryBuilder(StringBuilder sb)
/// </summary>
public QueryBuilder Take(int count)
{
_sb.Append(" TOP ").Append(count);
if (count >= 0)
_sb.Append(" TOP ").Append(count);
return this;
}

public QueryBuilder AddParameter(string parameterName)
{
_sb.Append(" @").Append(parameterName);
if (!string.IsNullOrWhiteSpace(parameterName))
_sb.Append(" @").Append(parameterName);
return this;
}

Expand All @@ -39,6 +41,9 @@ public QueryBuilder AddParameter(string parameterName)
/// </summary>
public QueryBuilder AddAttribute(string attributeName, string aliasName = AliasName)
{
if (string.IsNullOrWhiteSpace(attributeName))
return this;

_sb.Append(' ');

if (!string.IsNullOrWhiteSpace(aliasName))
Expand Down Expand Up @@ -67,7 +72,8 @@ public QueryBuilder AddSeparator()

public QueryBuilder Remove(int count = 1)
{
_sb.Length -= count;
if (count > 0)
_sb.Length -= count;
return this;
}

Expand All @@ -76,6 +82,9 @@ public QueryBuilder Remove(int count = 1)
/// </summary>
public QueryBuilder AddTable(Table table, string aliasName = AliasName)
{
if (table == null)
return this;

_sb.Append(" FROM ");

if (!string.IsNullOrWhiteSpace(table.Schema))
Expand All @@ -93,13 +102,20 @@ public QueryBuilder AddTable(Table table, string aliasName = AliasName)
return this;
}

internal void AppendCondition(string condition) => _sb.Append(" WHERE ").Append(condition);
internal void AppendCondition(string condition)
{
if (!string.IsNullOrWhiteSpace(condition))
_sb.Append(" WHERE ").Append(condition);
}

/// <summary>
/// Add [ and ] to column, table and function names
/// </summary>
private void AppendEscapedValue(string attributeName)
{
if (string.IsNullOrWhiteSpace(attributeName))
return;

if (attributeName.StartsWith("[") && attributeName.EndsWith("]"))
{
_sb.Append(attributeName);
Expand Down
4 changes: 2 additions & 2 deletions 01-Core/Jinget.Core/ExpressionToSql/Internal/Select.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ internal Select(Expression<Func<T, R>> select, int? take, Table table)
_table = table;
}

internal override (QueryBuilder query, Dictionary<string, object>? parameters) ToSql(QueryBuilder query)
internal override (QueryBuilder query, Dictionary<string, object?>? parameters) ToSql(QueryBuilder query)
{
if (_take.HasValue)
{
Expand Down Expand Up @@ -50,7 +50,7 @@ private static IEnumerable<Expression> GetExpressions(Type type, Expression body
var propertyInfos = type.GetWritableProperties();
return propertyInfos.Values.Select(pi => Expression.Property(body, pi));
default:
return new[] { body };
return [body];
}
}

Expand Down
38 changes: 22 additions & 16 deletions 01-Core/Jinget.Core/ExpressionToSql/Internal/Where.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Text;
using Jinget.Core.Exceptions;

#pragma warning disable CS8604 // Possible null reference argument.
namespace Jinget.Core.ExpressionToSql.Internal
{
public class Where<T, R> : Query
Expand All @@ -21,29 +22,29 @@ internal Where(Select<T, R> select, Expression<Func<T, bool>> where)
_where = where;
}

internal override (QueryBuilder query, Dictionary<string, object> parameters) ToSql(QueryBuilder query)
internal override (QueryBuilder query, Dictionary<string, object?> parameters) ToSql(QueryBuilder query)
{
_select.ToSql(query);

var i = 1;

if (_where is null)
return (query, new Dictionary<string, object>());
return (query, new Dictionary<string, object?>());

var where = Recurse(ref i, _where.Body, true);
query.AppendCondition(@where.ToString());
var where = Where<T, R>.Recurse(ref i, _where.Body, true);
query.AppendCondition(where.ToString());
return (query, @where.Parameters);
}

private WherePart Recurse(ref int i, Expression expression, bool isUnary = false, string? prefix = null, string? postfix = null)
private static WherePart Recurse(ref int i, Expression expression, bool isUnary = false, string? prefix = null, string? postfix = null)
{
if (expression is UnaryExpression unary)
{
return WherePart.Concat(NodeTypeToString(unary.NodeType), Recurse(ref i, unary.Operand, true));
return WherePart.Concat(NodeTypeToString(unary.NodeType), Where<T, R>.Recurse(ref i, unary.Operand, true));
}
if (expression is BinaryExpression binary)
{
return WherePart.Concat(Recurse(ref i, binary.Left), NodeTypeToString(binary.NodeType), Recurse(ref i, binary.Right));
return WherePart.Concat(Where<T, R>.Recurse(ref i, binary.Left), NodeTypeToString(binary.NodeType), Where<T, R>.Recurse(ref i, binary.Right));
}
if (expression is ConstantExpression constant)
{
Expand All @@ -65,7 +66,7 @@ private WherePart Recurse(ref int i, Expression expression, bool isUnary = false
case PropertyInfo property:
if (isUnary && member.Type == typeof(bool))
{
return WherePart.Concat(Recurse(ref i, member), "=", WherePart.IsParameter(i++, true));
return WherePart.Concat(Where<T, R>.Recurse(ref i, member), "=", WherePart.IsParameter(i++, true));
}

if (((MemberExpression)expression).Expression.NodeType == ExpressionType.Constant)

Check warning on line 72 in 01-Core/Jinget.Core/ExpressionToSql/Internal/Where.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.

Check warning on line 72 in 01-Core/Jinget.Core/ExpressionToSql/Internal/Where.cs

View workflow job for this annotation

GitHub Actions / releasePreview

Dereference of a possibly null reference.
Expand All @@ -91,17 +92,17 @@ private WherePart Recurse(ref int i, Expression expression, bool isUnary = false
// %xxx LIKE queries:
if (methodCall.Method == typeof(string).GetMethod("StartsWith", [typeof(string)]))
{
return WherePart.Concat(Recurse(ref i, methodCall.Object), "LIKE", Recurse(ref i, methodCall.Arguments[0], postfix: "%"));
return WherePart.Concat(Where<T, R>.Recurse(ref i, methodCall.Object), "LIKE", Where<T, R>.Recurse(ref i, methodCall.Arguments[0], postfix: "%"));
}
// xxx% LIKE queries:
if (methodCall.Method == typeof(string).GetMethod("EndsWith", [typeof(string)]))
{
return WherePart.Concat(Recurse(ref i, methodCall.Object), "LIKE", Recurse(ref i, methodCall.Arguments[0], prefix: "%"));
return WherePart.Concat(Where<T, R>.Recurse(ref i, methodCall.Object), "LIKE", Where<T, R>.Recurse(ref i, methodCall.Arguments[0], prefix: "%"));
}
// %xxx% LIKE queries:
if (methodCall.Method == typeof(string).GetMethod("Contains", [typeof(string)]))
{
return WherePart.Concat(Recurse(ref i, methodCall.Object), "LIKE", Recurse(ref i, methodCall.Arguments[0], prefix: "%", postfix: "%"));
return WherePart.Concat(Where<T, R>.Recurse(ref i, methodCall.Object), "LIKE", Where<T, R>.Recurse(ref i, methodCall.Arguments[0], prefix: "%", postfix: "%"));
}
// IN queries:
if (methodCall.Method.Name == "Contains")
Expand All @@ -123,7 +124,7 @@ private WherePart Recurse(ref int i, Expression expression, bool isUnary = false
throw new JingetException("Jinget Says: Unsupported method call: " + methodCall.Method.Name);
}
var values = (IEnumerable)GetValue(collection);
return WherePart.Concat(Recurse(ref i, property), "IN", WherePart.IsCollection(ref i, values));
return WherePart.Concat(Where<T, R>.Recurse(ref i, property), "IN", WherePart.IsCollection(ref i, values));
}
// column.ToString() OR Convert.ToString(column) queries
if (methodCall.Method.Name == "ToString")
Expand Down Expand Up @@ -156,7 +157,7 @@ private WherePart Recurse(ref int i, Expression expression, bool isUnary = false
//column.SomeMethod().ToUpper() AND SomeMethod(column).ToUpper()
if (methodCall.Object.NodeType == ExpressionType.Call)
{
return WherePart.IsFunction(Recurse(ref i, methodCall.Object).Sql, methodCall.Method.Name);
return WherePart.IsFunction(Where<T, R>.Recurse(ref i, methodCall.Object).Sql, methodCall.Method.Name);
}
}
}
Expand Down Expand Up @@ -229,11 +230,15 @@ public static WherePart Cast(string column, string method) =>
Sql = $"CAST({column} AS {ToSqlSyntax(method)})"
};

public static WherePart IsFunction(string column, string method) =>
new()
public static WherePart IsFunction(string? column, string method)
{
if (string.IsNullOrWhiteSpace(column))
return new WherePart();
return new()
{
Sql = $"{ToSqlSyntax(method).Replace("@P1", column)}"
};
}

public static WherePart IsParameter(int count, object? value) => new()
{
Expand Down Expand Up @@ -286,4 +291,5 @@ public static WherePart Concat(WherePart left, string @operator, WherePart right

public override string? ToString() => Sql;
}
}
}
#pragma warning restore CS8604 // Possible null reference argument.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public static class IDictionaryExtensions
/// in the first collection will be merged and duplicate keys will be ignored
/// </summary>
/// <param name="overwrite">if set to true, then duplicate keys from second collection will be overwritten to the first collection</param>
public static IDictionary<string, TValue>? Merge<TValue>(this IDictionary<string, TValue>? first, IDictionary<string, TValue>? second, bool overwrite = false)
public static IDictionary<string, TValue?>? Merge<TValue>(this IDictionary<string, TValue?>? first, IDictionary<string, TValue?>? second, bool overwrite = false)
{
if (first == null && second == null)
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ public static void ApplyCorrectYeKe(this IDbCommand command)
case DbType.String:
case DbType.StringFixedLength:
case DbType.Xml:
parameter.Value = parameter.Value.ToString().ApplyCorrectYeKe();
if (parameter.Value != null)
parameter.Value = parameter.Value.ToString().ApplyCorrectYeKe();
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public static void SafeOpen(this IDbConnection connection)
connection.Open();
}

private static (string queryText, Dictionary<string, object>? queryParameters) PrepareQuery(Query sql, object? param)
private static (string queryText, Dictionary<string, object?>? queryParameters) PrepareQuery(Query sql, object? param)
{
var query = sql.ToSql();
var queryText = query.query.ToString();
Expand Down Expand Up @@ -74,7 +74,6 @@ private static (IEnumerable<R> Data, int TotalCount) ExecQuery<R>(
Query sql,
object? param,
IDbTransaction? transaction,
bool buffered,
int? commandTimeout,
CommandType? commandType)
{
Expand All @@ -93,10 +92,10 @@ private static (IEnumerable<R> Data, int TotalCount) ExecQuery<R>(
public static async Task<(IEnumerable<R> Data, int TotalCount)> QueryAsync<T, R>(this IDbConnection cnn, Where<T, R> sql, object? param = null, IDbTransaction? transaction = null, int? commandTimeout = null, CommandType? commandType = null)
=> await ExecQueryAsync<R>(cnn, sql, param, transaction, commandTimeout, commandType);

public static (IEnumerable<R> Data, int TotalCount) Query<T, R>(this IDbConnection cnn, Select<T, R> sql, object? param = null, IDbTransaction? transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null)
=> ExecQuery<R>(cnn, sql, param, transaction, buffered, commandTimeout, commandType);
public static (IEnumerable<R> Data, int TotalCount) Query<T, R>(this IDbConnection cnn, Select<T, R> sql, object? param = null, IDbTransaction? transaction = null, int? commandTimeout = null, CommandType? commandType = null)
=> ExecQuery<R>(cnn, sql, param, transaction, commandTimeout, commandType);

public static (IEnumerable<R> Data, int TotalCount) Query<T, R>(this IDbConnection cnn, Where<T, R> sql, object? param = null, IDbTransaction? transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null)
=> ExecQuery<R>(cnn, sql, param, transaction, buffered, commandTimeout, commandType);
public static (IEnumerable<R> Data, int TotalCount) Query<T, R>(this IDbConnection cnn, Where<T, R> sql, object? param = null, IDbTransaction? transaction = null, int? commandTimeout = null, CommandType? commandType = null)
=> ExecQuery<R>(cnn, sql, param, transaction, commandTimeout, commandType);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public static class EnumExtensions
/// Get Name property of Display attribute for a specific enum value
/// If no Name is set on a field, then the stringfied value will be returned
/// </summary>
public static string GetDisplayName(this Enum value)
public static string? GetDisplayName(this Enum value)
{
var fi = value.GetType().GetField(value.ToString());
if (fi is null)
Expand Down
Loading

0 comments on commit bf64292

Please sign in to comment.