Skip to content

Commit

Permalink
[fix]表达式拼接selects子句时,不要检测到Or就加上圆括号,否则出现语法错误
Browse files Browse the repository at this point in the history
  • Loading branch information
nnhy committed Jul 28, 2024
1 parent 79a3c25 commit 0e3091f
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 156 deletions.
6 changes: 3 additions & 3 deletions XCode/Model/ConcatExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public class ConcatExpression : Expression
{
#region 属性
/// <summary>内置表达式集合</summary>
public IList<Expression> Expressions { get; set; } = new List<Expression>();
public IList<Expression> Expressions { get; set; } = [];

/// <summary>是否为空</summary>
public override Boolean IsEmpty => Expressions.Count == 0;
Expand All @@ -21,7 +21,7 @@ public ConcatExpression() { }

/// <summary>实例化</summary>
/// <param name="exp"></param>
public ConcatExpression(String exp) => Expressions.Add(new Expression(exp));
public ConcatExpression(String exp) => Expressions.Add(new Expression(exp) { DetectOr = false });
#endregion

#region 方法
Expand All @@ -32,7 +32,7 @@ public ConcatExpression And(String exp)
{
if (String.IsNullOrEmpty(exp)) return this;

Expressions.Add(new Expression(exp));
Expressions.Add(new Expression(exp) { DetectOr = false });

return this;
}
Expand Down
5 changes: 4 additions & 1 deletion XCode/Model/Expression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ public class Expression
/// <summary>文本表达式</summary>
public String? Text { get; private set; }

/// <summary>是否检测Or关键字并加上括号。默认true</summary>
public Boolean DetectOr { get; set; } = true;

/// <summary>是否为空</summary>
public virtual Boolean IsEmpty => Text.IsNullOrEmpty();

Expand Down Expand Up @@ -54,7 +57,7 @@ public virtual void GetString(IDatabase? db, StringBuilder builder, IDictionary<
var txt = Text;
if (txt.IsNullOrEmpty()) return;

if (_regOr.IsMatch(txt))
if (DetectOr && _regOr.IsMatch(txt))
builder.AppendFormat("({0})", txt);
else
builder.Append(txt);
Expand Down
301 changes: 149 additions & 152 deletions XCode/Model/WhereExpression.cs
Original file line number Diff line number Diff line change
@@ -1,197 +1,194 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using NewLife.Collections;
using XCode.DataAccessLayer;

namespace XCode
namespace XCode;

/// <summary>操作符</summary>
public enum Operator
{
/// <summary>操作符</summary>
public enum Operator
{
/// <summary>与,交集</summary>
And,
/// <summary>与,交集</summary>
And,

/// <summary>或,并集</summary>
Or,
/// <summary>或,并集</summary>
Or,

/// <summary>空格</summary>
Space
};
/// <summary>空格</summary>
Space
};

/// <summary>条件表达式</summary>
public class WhereExpression : Expression, IEnumerable<Expression>
{
#region 属性
/// <summary>左节点</summary>
public Expression Left { get; set; }
/// <summary>条件表达式</summary>
public class WhereExpression : Expression, IEnumerable<Expression>
{
#region 属性
/// <summary>左节点</summary>
public Expression Left { get; set; } = null!;

/// <summary>右节点</summary>
public Expression Right { get; set; }
/// <summary>右节点</summary>
public Expression Right { get; set; } = null!;

/// <summary>是否And</summary>
public Operator Operator { get; set; }
/// <summary>是否And</summary>
public Operator Operator { get; set; }

/// <summary>是否为空</summary>
public override Boolean IsEmpty => (Left == null || Left.IsEmpty) && (Right == null || Right.IsEmpty);
#endregion
/// <summary>是否为空</summary>
public override Boolean IsEmpty => (Left == null || Left.IsEmpty) && (Right == null || Right.IsEmpty);
#endregion

#region 构造
/// <summary>实例化</summary>
public WhereExpression() { }
#region 构造
/// <summary>实例化</summary>
public WhereExpression() { }

/// <summary>实例化</summary>
/// <param name="left"></param>
/// <param name="op"></param>
/// <param name="right"></param>
public WhereExpression(Expression left, Operator op, Expression right)
{
Left = Flatten(left);
Operator = op;
Right = Flatten(right);
}
#endregion

#region 方法
/// <summary>输出条件表达式的字符串表示,遍历表达式集合并拼接起来</summary>
/// <param name="db">数据库</param>
/// <param name="builder"></param>
/// <param name="ps">参数字典</param>
/// <returns></returns>
public override void GetString(IDatabase? db, StringBuilder builder, IDictionary<String, Object>? ps)
{
if (IsEmpty) return;
/// <summary>实例化</summary>
/// <param name="left"></param>
/// <param name="op"></param>
/// <param name="right"></param>
public WhereExpression(Expression left, Operator op, Expression right)
{
Left = Flatten(left);
Operator = op;
Right = Flatten(right);
}
#endregion

#region 方法
/// <summary>输出条件表达式的字符串表示,遍历表达式集合并拼接起来</summary>
/// <param name="db">数据库</param>
/// <param name="builder"></param>
/// <param name="ps">参数字典</param>
/// <returns></returns>
public override void GetString(IDatabase? db, StringBuilder builder, IDictionary<String, Object>? ps)
{
if (IsEmpty) return;

// 递归构建,下级运算符优先级较低时加括号
// 递归构建,下级运算符优先级较低时加括号

var len = builder.Length;
var len = builder.Length;

// 左侧表达式
GetString(db, builder, ps, Left);
// 左侧表达式
GetString(db, builder, ps, Left);

// 右侧表达式
var sb = Pool.StringBuilder.Get();
GetString(db, sb, ps, Right);
// 右侧表达式
var sb = Pool.StringBuilder.Get();
GetString(db, sb, ps, Right);

// 中间运算符
if (builder.Length > len && sb.Length > 0)
// 中间运算符
if (builder.Length > len && sb.Length > 0)
{
switch (Operator)
{
switch (Operator)
{
case Operator.And: builder.Append(" And "); break;
case Operator.Or: builder.Append(" Or "); break;
case Operator.Space: builder.Append(' '); break;
default: break;
}
case Operator.And: builder.Append(" And "); break;
case Operator.Or: builder.Append(" Or "); break;
case Operator.Space: builder.Append(' '); break;
default: break;
}

builder.Append(sb.Put(true));
}

private void GetString(IDatabase? db, StringBuilder builder, IDictionary<String, Object> ps, Expression exp)
{
exp = Flatten(exp);
if (exp == null || exp.IsEmpty) return;
builder.Append(sb.Put(true));
}

// 递归构建,下级运算符优先级较低时加括号
var bracket = false;
if (exp is WhereExpression where)
{
//if (where.IsEmpty) return;
private void GetString(IDatabase? db, StringBuilder builder, IDictionary<String, Object> ps, Expression exp)
{
exp = Flatten(exp);
if (exp == null || exp.IsEmpty) return;

if (where.Operator > Operator) bracket = true;
}
// 递归构建,下级运算符优先级较低时加括号
var bracket = false;
if (exp is WhereExpression where)
{
//if (where.IsEmpty) return;

if (bracket) builder.Append('(');
exp.GetString(db, builder, ps);
if (bracket) builder.Append(')');
if (where.Operator > Operator) bracket = true;
}

/// <summary>拉平表达式,避免空子项</summary>
/// <param name="exp"></param>
/// <returns></returns>
private Expression Flatten(Expression exp)
{
if (exp == null) return null;
if (bracket) builder.Append('(');
exp.GetString(db, builder, ps);
if (bracket) builder.Append(')');
}

if (exp is WhereExpression where)
{
// 左右为空,返回空
if (where.Left == null && where.Right == null) return null;
/// <summary>拉平表达式,避免空子项</summary>
/// <param name="exp"></param>
/// <returns></returns>
private Expression Flatten(Expression exp)
{
if (exp == null) return null;

// 其中一边为空,递归拉平另一边
if (where.Left == null) return Flatten(where.Right);
if (where.Right == null) return Flatten(where.Left);
}
if (exp is WhereExpression where)
{
// 左右为空,返回空
if (where.Left == null && where.Right == null) return null;

return exp;
// 其中一边为空,递归拉平另一边
if (where.Left == null) return Flatten(where.Right);
if (where.Right == null) return Flatten(where.Left);
}

///// <summary>访问表达式</summary>
///// <param name="visitor"></param>
///// <returns></returns>
//public Expression Visit(Func<Expression, Boolean> visitor)
//{
// if (Left != null)
// {
// var rs = visitor(Left);
// if (rs) return Left;

// if (Left is WhereExpression where)
// {
// var exp = where.Visit(visitor);
// if (exp != null) return exp;
// }
// }

// if (Right != null)
// {
// var rs = visitor(Right);
// if (rs) return Right;

// if (Right is WhereExpression where)
// {
// var exp = where.Visit(visitor);
// if (exp != null) return exp;
// }
// }

// return null;
//}

/// <summary>枚举</summary>
/// <returns></returns>
public IEnumerator<Expression> GetEnumerator()
return exp;
}

///// <summary>访问表达式</summary>
///// <param name="visitor"></param>
///// <returns></returns>
//public Expression Visit(Func<Expression, Boolean> visitor)
//{
// if (Left != null)
// {
// var rs = visitor(Left);
// if (rs) return Left;

// if (Left is WhereExpression where)
// {
// var exp = where.Visit(visitor);
// if (exp != null) return exp;
// }
// }

// if (Right != null)
// {
// var rs = visitor(Right);
// if (rs) return Right;

// if (Right is WhereExpression where)
// {
// var exp = where.Visit(visitor);
// if (exp != null) return exp;
// }
// }

// return null;
//}

/// <summary>枚举</summary>
/// <returns></returns>
public IEnumerator<Expression> GetEnumerator()
{
if (Left != null)
{
if (Left != null)
{
yield return Left;
yield return Left;

if (Left is WhereExpression where)
if (Left is WhereExpression where)
{
foreach (var item in where)
{
foreach (var item in where)
{
yield return item;
}
yield return item;
}
}
}

if (Right != null)
{
yield return Right;
if (Right != null)
{
yield return Right;

if (Right is WhereExpression where)
if (Right is WhereExpression where)
{
foreach (var item in where)
{
foreach (var item in where)
{
yield return item;
}
yield return item;
}
}
}

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
#endregion
}

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
#endregion
}

0 comments on commit 0e3091f

Please sign in to comment.