diff --git a/sdmap/src/sdmap.ext.Dapper/sdmap.ext.Dapper.csproj b/sdmap/src/sdmap.ext.Dapper/sdmap.ext.Dapper.csproj
index 796b482..7e5954e 100644
--- a/sdmap/src/sdmap.ext.Dapper/sdmap.ext.Dapper.csproj
+++ b/sdmap/src/sdmap.ext.Dapper/sdmap.ext.Dapper.csproj
@@ -5,6 +5,7 @@
sdmap.ext.Dapper
sdmap.ext.Dapper
dynamic sql;sdmap;dapper
+ true
For more information, please view:
https://github.com/sdcb/sdmap/blob/master/ReleaseNotes.md
@@ -13,13 +14,13 @@ https://github.com/sdcb/sdmap/blob/master/ReleaseNotes.md
false
false
false
- 0.16.4
+ 0.16.5
Dapper extensions for sdmap.
https://github.com/sdcb/sdmap
sdcb
MIT
- 0.16.4
- 0.16.4
+ 0.16.5
+ 0.16.5
LICENSE
true
true
diff --git a/sdmap/src/sdmap.ext/sdmap.ext.csproj b/sdmap/src/sdmap.ext/sdmap.ext.csproj
index ba1945c..4aaa91f 100644
--- a/sdmap/src/sdmap.ext/sdmap.ext.csproj
+++ b/sdmap/src/sdmap.ext/sdmap.ext.csproj
@@ -5,6 +5,7 @@
sdmap.ext
sdmap.ext
dynamic sql;sdmap
+ true
For more information, please view:
https://github.com/sdcb/sdmap/blob/master/ReleaseNotes.md
@@ -13,13 +14,13 @@ https://github.com/sdcb/sdmap/blob/master/ReleaseNotes.md
false
false
false
- 0.16.4
+ 0.16.5
Useful extensions for sdmap/Dapper.
https://github.com/sdcb/sdmap
sdcb
MIT
- 0.16.4
- 0.16.4
+ 0.16.5
+ 0.16.5
LICENSE
true
true
diff --git a/sdmap/src/sdmap/Macros/Implements/RuntimeMacros.cs b/sdmap/src/sdmap/Macros/Implements/RuntimeMacros.cs
index 052c841..d6cfd77 100644
--- a/sdmap/src/sdmap/Macros/Implements/RuntimeMacros.cs
+++ b/sdmap/src/sdmap/Macros/Implements/RuntimeMacros.cs
@@ -178,7 +178,7 @@ public static Result IsEqual(OneCallContext context,
string syntax = (string)arguments[0];
var val = GetPropValue(self, syntax);
var compare = arguments[1];
- if (IsEqual(val, compare))
+ if (ValueComparer.Compare(val, compare) is ComparisonResult.AreEqual)
return MacroUtil.EvalToString(arguments[2], context, self);
return Empty;
@@ -197,14 +197,14 @@ public static Result IsNotEqual(OneCallContext context,
string syntax = (string)arguments[0];
var val = GetPropValue(self, syntax);
var compare = arguments[1];
- if (!IsEqual(val, compare))
+ if (ValueComparer.Compare(val, compare) is not ComparisonResult.AreEqual)
return MacroUtil.EvalToString(arguments[2], context, self);
return Empty;
}
[Macro("isLessThan")]
- [MacroArguments(SdmapTypes.Syntax, SdmapTypes.Number, SdmapTypes.StringOrSql)]
+ [MacroArguments(SdmapTypes.Syntax, SdmapTypes.Any, SdmapTypes.StringOrSql)]
public static Result IsLessThan(OneCallContext context,
string ns, object self, object[] arguments)
{
@@ -214,16 +214,17 @@ public static Result IsLessThan(OneCallContext context,
if (prop == null) return RequirePropNotNull(arguments[0]);
string syntax = (string)arguments[0];
- var val = GetPropValue(self, syntax);
- var compare = Convert.ToDouble(arguments[1]);
- if (Convert.ToDouble(val) < compare)
+ var left = GetPropValue(self, syntax);
+ var right = arguments[1];
+
+ if (ValueComparer.Compare(left, right) is ComparisonResult.LeftIsLess)
return MacroUtil.EvalToString(arguments[2], context, self);
return Empty;
}
[Macro("isGreaterThan")]
- [MacroArguments(SdmapTypes.Syntax, SdmapTypes.Number, SdmapTypes.StringOrSql)]
+ [MacroArguments(SdmapTypes.Syntax, SdmapTypes.Any, SdmapTypes.StringOrSql)]
public static Result IsGreaterThan(OneCallContext context,
string ns, object self, object[] arguments)
{
@@ -233,16 +234,17 @@ public static Result IsGreaterThan(OneCallContext context,
if (prop == null) return RequirePropNotNull(arguments[0]);
string syntax = (string)arguments[0];
- var val = GetPropValue(self, syntax);
- var compare = Convert.ToDouble(arguments[1]);
- if (Convert.ToDouble(val) > compare)
+ var left = GetPropValue(self, syntax);
+ var right = arguments[1];
+
+ if (ValueComparer.Compare(left, right) is ComparisonResult.LeftIsGreater)
return MacroUtil.EvalToString(arguments[2], context, self);
return Empty;
}
[Macro("isLessEqual")]
- [MacroArguments(SdmapTypes.Syntax, SdmapTypes.Number, SdmapTypes.StringOrSql)]
+ [MacroArguments(SdmapTypes.Syntax, SdmapTypes.Any, SdmapTypes.StringOrSql)]
public static Result IsLessEqual(OneCallContext context,
string ns, object self, object[] arguments)
{
@@ -252,16 +254,17 @@ public static Result IsLessEqual(OneCallContext context,
if (prop == null) return RequirePropNotNull(arguments[0]);
string syntax = (string)arguments[0];
- var val = GetPropValue(self, syntax);
- var compare = Convert.ToDouble(arguments[1]);
- if (Convert.ToDouble(val) <= compare)
+ var left = GetPropValue(self, syntax);
+ var right = arguments[1];
+
+ if (ValueComparer.Compare(left, right) is ComparisonResult.LeftIsLess or ComparisonResult.AreEqual)
return MacroUtil.EvalToString(arguments[2], context, self);
return Empty;
}
[Macro("isGreaterEqual")]
- [MacroArguments(SdmapTypes.Syntax, SdmapTypes.Number, SdmapTypes.StringOrSql)]
+ [MacroArguments(SdmapTypes.Syntax, SdmapTypes.Any, SdmapTypes.StringOrSql)]
public static Result IsGreaterEqual(OneCallContext context,
string ns, object self, object[] arguments)
{
@@ -271,9 +274,10 @@ public static Result IsGreaterEqual(OneCallContext context,
if (prop == null) return RequirePropNotNull(arguments[0]);
string syntax = (string)arguments[0];
- var val = GetPropValue(self, syntax);
- var compare = Convert.ToDouble(arguments[1]);
- if (Convert.ToDouble(val) >= compare)
+ var left = GetPropValue(self, syntax);
+ var right = arguments[1];
+
+ if (ValueComparer.Compare(left, right) is ComparisonResult.LeftIsGreater or ComparisonResult.AreEqual)
return MacroUtil.EvalToString(arguments[2], context, self);
return Empty;
@@ -477,40 +481,6 @@ public static object GetPropValue(object self, string prop)
}
}
- public static bool IsEqual(object v1, object v2)
- {
- if (v1 is string str)
- return str.Equals((string)v2);
-
- if (v1 is bool b)
- return b.Equals((bool)v2);
-
- if (v1 is int integer)
- return integer.Equals(Convert.ToInt32(v2));
-
- if (v1 is long longValue)
- return longValue.Equals(Convert.ToInt64(v2));
-
- if (v1 is double db)
- return db.Equals(Convert.ToDouble(v2));
-
- if (v1 is decimal dm)
- return dm.Equals(Convert.ToDecimal(v2));
-
- if (v1 is DateTime date)
- return date.Equals((DateTime)v2);
-
- if (v1 is Enum @enum)
- {
- if (v2 is string v2s)
- return @enum.ToString() == v2s;
- if (v2 is double v2d)
- return Convert.ToInt64(@enum) == v2d;
- }
-
- return v1 == v2;
- }
-
public static bool IsEmpty(object v)
{
if (v == null)
@@ -528,4 +498,4 @@ public static bool ArrayEmpty(IEnumerable arr)
return !arr.GetEnumerator().MoveNext();
}
}
-}
+}
\ No newline at end of file
diff --git a/sdmap/src/sdmap/Macros/Implements/ValueComparer.cs b/sdmap/src/sdmap/Macros/Implements/ValueComparer.cs
new file mode 100644
index 0000000..8511ec8
--- /dev/null
+++ b/sdmap/src/sdmap/Macros/Implements/ValueComparer.cs
@@ -0,0 +1,140 @@
+using System;
+using System.Linq;
+using System.Reflection;
+// ReSharper disable SuggestBaseTypeForParameter
+
+namespace sdmap.Macros.Implements;
+
+public enum ComparisonResult : byte
+{
+ Incomparable = 1,
+ AreEqual,
+ LeftIsGreater,
+ LeftIsLess
+}
+
+internal static class ValueComparer
+{
+ public static ComparisonResult Compare(object left, object right)
+ => CompareImpl(left, right) switch
+ {
+ null => ComparisonResult.Incomparable,
+ 0 => ComparisonResult.AreEqual,
+ > 0 => ComparisonResult.LeftIsGreater,
+ < 0 => ComparisonResult.LeftIsLess
+ };
+
+ private static int? CompareImpl(object left, object right)
+ => left switch
+ {
+ null => right is null ? 0 : null,
+ not null when right is null => null,
+
+ byte byteValue => byteValue.CompareTo(Convert.ToByte(right)),
+ sbyte sByteValue => sByteValue.CompareTo(Convert.ToSByte(right)),
+ short shortValue => shortValue.CompareTo(Convert.ToInt16(right)),
+ ushort ushortValue => ushortValue.CompareTo(Convert.ToUInt16(right)),
+
+ int intValue => intValue.CompareTo(Convert.ToInt32(right)),
+ uint uIntValue => uIntValue.CompareTo(Convert.ToUInt32(right)),
+ long longValue => longValue.CompareTo(Convert.ToInt64(right)),
+ ulong uLongValue => uLongValue.CompareTo(Convert.ToUInt64(right)),
+
+ float floatValue => floatValue.CompareTo(Convert.ToSingle(right)),
+ double doubleValue => doubleValue.CompareTo(Convert.ToDouble(right)),
+ decimal decimalValue => decimalValue.CompareTo(Convert.ToDecimal(right)),
+
+ Enum enumValue => Compare(enumValue, right),
+ IComparable comparable => Compare(comparable, right),
+
+ _ => null
+ };
+
+ private static int? Compare(Enum leftEnum, object right)
+ {
+ if (right is Enum rightEnum)
+ {
+ return leftEnum.GetType() == rightEnum.GetType()
+ ? leftEnum.CompareTo(rightEnum)
+ : null;
+ }
+
+ return EnumParser.TryParse(leftEnum.GetType(), right.ToString(), out var parsed)
+ ? leftEnum.CompareTo(parsed)
+ : null;
+ }
+
+ private static int? Compare(IComparable comparable, object right)
+ {
+ var leftType = comparable.GetType();
+
+ if (leftType == right.GetType())
+ {
+ return comparable.CompareTo(right);
+ }
+
+ return TryParse(leftType, right.ToString(), out var parsed)
+ ? comparable.CompareTo(parsed)
+ : null;
+
+ static bool TryParse(Type targetType, string input, out object parsed)
+ {
+ if (targetType == typeof(Guid))
+ {
+ var result = Guid.TryParse(input, out var parsedValue);
+ parsed = parsedValue;
+ return result;
+ }
+
+ if (targetType == typeof(TimeSpan))
+ {
+ var result = TimeSpan.TryParse(input, out var parsedValue);
+ parsed = parsedValue;
+ return result;
+ }
+
+ if (targetType == typeof(DateTime))
+ {
+ var result = DateTime.TryParse(input, out var parsedValue);
+ parsed = parsedValue;
+ return result;
+ }
+
+ if (targetType == typeof(DateTimeOffset))
+ {
+ var result = DateTimeOffset.TryParse(input, out var parsedValue);
+ parsed = parsedValue;
+ return result;
+ }
+
+ parsed = null;
+ return false;
+ }
+ }
+
+ private static class EnumParser
+ {
+ private static readonly MethodInfo TryParseMethod
+ = typeof(Enum)
+ .GetMethods(BindingFlags.Public | BindingFlags.Static)
+ .Single(method =>
+ method.Name == nameof(Enum.TryParse)
+ && method.IsGenericMethodDefinition
+ && method.ReturnType == typeof(bool)
+ && method.GetParameters().Length == 3
+ && method.GetParameters().First().ParameterType == typeof(string)
+ );
+
+ public static bool TryParse(Type enumType, string value, out object parsed)
+ {
+ var parameters = new object[] { value, true, null };
+
+ var result = TryParseMethod
+ .MakeGenericMethod(enumType)
+ .Invoke(obj: null, parameters);
+
+ parsed = parameters[2];
+ return (bool)result;
+ }
+ }
+}
\ No newline at end of file
diff --git a/sdmap/src/sdmap/sdmap.csproj b/sdmap/src/sdmap/sdmap.csproj
index cccd557..166e4fc 100644
--- a/sdmap/src/sdmap/sdmap.csproj
+++ b/sdmap/src/sdmap/sdmap.csproj
@@ -3,9 +3,11 @@
A template engine for writing dynamic sql.
net6;netstandard20
+ latest
sdmap
sdmap
dynamic sql;ibatis
+ true
https://github.com/sdcb/sdmap/blob/master/ReleaseNotes.md
git
@@ -13,9 +15,9 @@
false
false
false
- 0.16.4
- 0.16.4
- 0.16.4
+ 0.16.5
+ 0.16.5
+ 0.16.5
sdcb
MIT
https://github.com/sdcb/sdmap
diff --git a/sdmap/test/sdmap.test/ValueComparerTests.cs b/sdmap/test/sdmap.test/ValueComparerTests.cs
new file mode 100644
index 0000000..41b019a
--- /dev/null
+++ b/sdmap/test/sdmap.test/ValueComparerTests.cs
@@ -0,0 +1,103 @@
+using System;
+using System.Collections.Generic;
+using sdmap.Macros.Implements;
+using Xunit;
+
+namespace sdmap.test;
+
+using static ComparisonResult;
+
+public class ValueComparerTests
+{
+ [Theory]
+ [MemberData(nameof(Compare_Cases_Number))]
+ [MemberData(nameof(Compare_Cases_Enum))]
+ [MemberData(nameof(Compare_Cases_Guid))]
+ [MemberData(nameof(Compare_Cases_Timespan))]
+ [MemberData(nameof(Compare_Cases_DateTime))]
+ public void Compare(object left, object right, ComparisonResult expected)
+ {
+ var actual = ValueComparer.Compare(left, right);
+ Assert.Equal(expected, actual);
+ }
+
+ public static IEnumerable