From 8d37c6a3eee838e70cb7cc57187ca865f4363f78 Mon Sep 17 00:00:00 2001 From: zadykian Date: Wed, 30 Aug 2023 15:48:01 +0300 Subject: [PATCH 1/6] Improved value comparison in built-in macros --- .../sdmap/Macros/Implements/RuntimeMacros.cs | 40 +------- .../sdmap/Macros/Implements/ValueComparer.cs | 95 ++++++++++++++++++ sdmap/src/sdmap/sdmap.csproj | 1 + sdmap/test/sdmap.test/ValueComparerTests.cs | 96 +++++++++++++++++++ 4 files changed, 195 insertions(+), 37 deletions(-) create mode 100644 sdmap/src/sdmap/Macros/Implements/ValueComparer.cs create mode 100644 sdmap/test/sdmap.test/ValueComparerTests.cs diff --git a/sdmap/src/sdmap/Macros/Implements/RuntimeMacros.cs b/sdmap/src/sdmap/Macros/Implements/RuntimeMacros.cs index 052c841..4ee0a28 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.IsEqual(val, compare)) return MacroUtil.EvalToString(arguments[2], context, self); return Empty; @@ -197,7 +197,7 @@ 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.IsEqual(val, compare)) return MacroUtil.EvalToString(arguments[2], context, self); return Empty; @@ -477,40 +477,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 +494,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..3947ae3 --- /dev/null +++ b/sdmap/src/sdmap/Macros/Implements/ValueComparer.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +namespace sdmap.Macros.Implements; + +internal class ValueComparer : IComparer +{ + private ValueComparer() + { + } + + public static IComparer Instance { get; } = new ValueComparer(); + + public int Compare(object x, object y) + { + throw new NotImplementedException(); + } + + public static bool IsEqual(object v1, object v2) + => v1 switch + { + null => v2 is null, + not null when v2 is null => false, + + byte byteValue => byteValue.Equals(Convert.ToByte(v2)), + sbyte sByteValue => sByteValue.Equals(Convert.ToSByte(v2)), + short shortValue => shortValue.Equals(Convert.ToInt16(v2)), + ushort ushortValue => ushortValue.Equals(Convert.ToUInt16(v2)), + + int intValue => intValue.Equals(Convert.ToInt32(v2)), + uint uIntValue => uIntValue.Equals(Convert.ToUInt32(v2)), + long longValue => longValue.Equals(Convert.ToInt64(v2)), + ulong uLongValue => uLongValue.Equals(Convert.ToUInt64(v2)), + + float floatValue => floatValue.Equals(Convert.ToSingle(v2)), + double doubleValue => doubleValue.Equals(Convert.ToDouble(v2)), + decimal decimalValue => decimalValue.Equals(Convert.ToDecimal(v2)), + + Enum enumValue + => v2 is Enum other + ? enumValue.Equals(other) + : EnumParser.TryParse(enumValue.GetType(), v2.ToString(), out var parsed) + && enumValue.Equals(parsed), + + Guid guid + => v2 is Guid other + ? guid.Equals(other) + : Guid.TryParse(v2.ToString(), out var parsed) && guid.Equals(parsed), + + TimeSpan timeSpan + => v2 is TimeSpan other + ? timeSpan.Equals(other) + : TimeSpan.TryParse(v2.ToString(), out var parsed) && timeSpan.Equals(parsed), + + DateTime dateTime + => v2 is DateTime other + ? dateTime.Equals(other) + : DateTime.TryParse(v2.ToString(), out var parsed) && dateTime.Equals(parsed), + + DateTimeOffset dateTimeOffset + => v2 is DateTimeOffset other + ? dateTimeOffset.Equals(other) + : DateTimeOffset.TryParse(v2.ToString(), out var parsed) && dateTimeOffset.Equals(parsed), + + _ => v1.Equals(v2) + }; + + 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..4488ec5 100644 --- a/sdmap/src/sdmap/sdmap.csproj +++ b/sdmap/src/sdmap/sdmap.csproj @@ -3,6 +3,7 @@ A template engine for writing dynamic sql. net6;netstandard20 + latest sdmap sdmap dynamic sql;ibatis diff --git a/sdmap/test/sdmap.test/ValueComparerTests.cs b/sdmap/test/sdmap.test/ValueComparerTests.cs new file mode 100644 index 0000000..be3430b --- /dev/null +++ b/sdmap/test/sdmap.test/ValueComparerTests.cs @@ -0,0 +1,96 @@ +using System; +using System.Collections.Generic; +using sdmap.Macros.Implements; +using Xunit; + +namespace sdmap.test; + +public class ValueComparerTests +{ + [Theory] + [MemberData(nameof(IsEqual_Cases_Number))] + [MemberData(nameof(IsEqual_Cases_Enum))] + [MemberData(nameof(IsEqual_Cases_Guid))] + [MemberData(nameof(IsEqual_Cases_Timespan))] + [MemberData(nameof(IsEqual_Cases_DateTime))] + public void IsEqual(object left, object right, bool areEqual) + { + var actual = ValueComparer.IsEqual(left, right); + Assert.Equal(areEqual, actual); + } + + public static IEnumerable IsEqual_Cases_Number() + { + yield return new object[] { 0, 0, true }; + yield return new object[] { 0, 0L, true }; + yield return new object[] { (short) 1, 1L, true }; + yield return new object[] { (byte) 1, (ulong) 1, true }; + + yield return new object[] { 1D, 1F, true }; + yield return new object[] { 1M, 1M, true }; + yield return new object[] { 1M, 1D, true }; + yield return new object[] { 1M, 0D, false }; + + yield return new object[] { 1M, "1", true }; + } + + public static IEnumerable IsEqual_Cases_Enum() + { + yield return new object[] { FirstEnum.One, FirstEnum.One, true }; + yield return new object[] { FirstEnum.One, FirstEnum.Two, false }; + yield return new object[] { FirstEnum.One, SecondEnum.One, false }; + yield return new object[] { FirstEnum.One, SecondEnum.Two, false }; + + yield return new object[] { FirstEnum.One, 1, true }; + yield return new object[] { FirstEnum.One, "1", true }; + yield return new object[] { FirstEnum.One, "One", true }; + yield return new object[] { FirstEnum.One, 1.0M, false }; + } + + public static IEnumerable IsEqual_Cases_Guid() + { + yield return new object[] + { + new Guid("01d1692d-2221-47cd-892b-4a6552c6a9cc"), + new Guid("01d1692d-2221-47cd-892b-4a6552c6a9cc"), + true + }; + + yield return new object[] + { + new Guid("01d1692d-2221-47cd-892b-4a6552c6a9cc"), + "01d1692d-2221-47cd-892b-4a6552c6a9cc", + true + }; + + yield return new object[] { Guid.NewGuid(), Guid.NewGuid(), false }; + + yield return new object[] + { + new Guid("01d1692d-2221-47cd-892b-4a6552c6a9cc"), + DateTime.Now, + false + }; + } + + public static IEnumerable IsEqual_Cases_Timespan() + { + yield return new object[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), true }; + yield return new object[] { TimeSpan.FromSeconds(1), "00:00:01", true }; + yield return new object[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(0), false }; + yield return new object[] { TimeSpan.FromSeconds(1), "10", false }; + yield return new object[] { TimeSpan.FromSeconds(1), DateTime.Now, false }; + } + + public static IEnumerable IsEqual_Cases_DateTime() + { + yield return new object[] { new DateTime(2023, 01, 01), new DateTime(2023, 01, 01), true }; + yield return new object[] { new DateTime(2023, 01, 01), new DateTime(1900, 01, 01), false }; + yield return new object[] { new DateTime(2023, 01, 01), "2023-01-01", true }; + yield return new object[] { DateTime.Now, TimeSpan.FromSeconds(0), false }; + } + + private enum FirstEnum { One = 1, Two = 2 } + + private enum SecondEnum { One = 1, Two = 2 } +} \ No newline at end of file From 0cb3e67ede4e216f2daf939267e417a4fc7c606f Mon Sep 17 00:00:00 2001 From: zadykian Date: Wed, 30 Aug 2023 19:29:45 +0300 Subject: [PATCH 2/6] implemented IComparable semantic in ValueComparer --- .../sdmap/Macros/Implements/RuntimeMacros.cs | 4 +- .../sdmap/Macros/Implements/ValueComparer.cs | 158 +++++++++++------- sdmap/test/sdmap.test/ValueComparerTests.cs | 93 ++++++----- 3 files changed, 154 insertions(+), 101 deletions(-) diff --git a/sdmap/src/sdmap/Macros/Implements/RuntimeMacros.cs b/sdmap/src/sdmap/Macros/Implements/RuntimeMacros.cs index 4ee0a28..c6638e1 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 (ValueComparer.IsEqual(val, compare)) + if (ValueComparer.Compare(val, compare) is ComparisonResult.AreEqual) return MacroUtil.EvalToString(arguments[2], context, self); return Empty; @@ -197,7 +197,7 @@ public static Result IsNotEqual(OneCallContext context, string syntax = (string)arguments[0]; var val = GetPropValue(self, syntax); var compare = arguments[1]; - if (!ValueComparer.IsEqual(val, compare)) + if (ValueComparer.Compare(val, compare) is not ComparisonResult.AreEqual) return MacroUtil.EvalToString(arguments[2], context, self); return Empty; diff --git a/sdmap/src/sdmap/Macros/Implements/ValueComparer.cs b/sdmap/src/sdmap/Macros/Implements/ValueComparer.cs index 3947ae3..e189a14 100644 --- a/sdmap/src/sdmap/Macros/Implements/ValueComparer.cs +++ b/sdmap/src/sdmap/Macros/Implements/ValueComparer.cs @@ -1,71 +1,117 @@ using System; -using System.Collections.Generic; using System.Linq; using System.Reflection; +// ReSharper disable SuggestBaseTypeForParameter namespace sdmap.Macros.Implements; -internal class ValueComparer : IComparer +[Flags] +public enum ComparisonResult : byte { - private ValueComparer() - { - } + Incomparable = 1, + AreEqual = 2, + LeftIsGreater = 4, + LeftIsLess = 8 +} + +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 + }; - public static IComparer Instance { get; } = new ValueComparer(); + private static int? CompareImpl(object left, object right) + => left switch + { + null => right is null ? 0 : null, + not null when right is null => null, - public int Compare(object x, object y) + 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) { - throw new NotImplementedException(); + 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; } - - public static bool IsEqual(object v1, object v2) - => v1 switch + + private static int? Compare(IComparable comparable, object right) + { + var leftType = comparable.GetType(); + + if (leftType == right.GetType()) { - null => v2 is null, - not null when v2 is null => false, - - byte byteValue => byteValue.Equals(Convert.ToByte(v2)), - sbyte sByteValue => sByteValue.Equals(Convert.ToSByte(v2)), - short shortValue => shortValue.Equals(Convert.ToInt16(v2)), - ushort ushortValue => ushortValue.Equals(Convert.ToUInt16(v2)), - - int intValue => intValue.Equals(Convert.ToInt32(v2)), - uint uIntValue => uIntValue.Equals(Convert.ToUInt32(v2)), - long longValue => longValue.Equals(Convert.ToInt64(v2)), - ulong uLongValue => uLongValue.Equals(Convert.ToUInt64(v2)), - - float floatValue => floatValue.Equals(Convert.ToSingle(v2)), - double doubleValue => doubleValue.Equals(Convert.ToDouble(v2)), - decimal decimalValue => decimalValue.Equals(Convert.ToDecimal(v2)), - - Enum enumValue - => v2 is Enum other - ? enumValue.Equals(other) - : EnumParser.TryParse(enumValue.GetType(), v2.ToString(), out var parsed) - && enumValue.Equals(parsed), - - Guid guid - => v2 is Guid other - ? guid.Equals(other) - : Guid.TryParse(v2.ToString(), out var parsed) && guid.Equals(parsed), - - TimeSpan timeSpan - => v2 is TimeSpan other - ? timeSpan.Equals(other) - : TimeSpan.TryParse(v2.ToString(), out var parsed) && timeSpan.Equals(parsed), - - DateTime dateTime - => v2 is DateTime other - ? dateTime.Equals(other) - : DateTime.TryParse(v2.ToString(), out var parsed) && dateTime.Equals(parsed), - - DateTimeOffset dateTimeOffset - => v2 is DateTimeOffset other - ? dateTimeOffset.Equals(other) - : DateTimeOffset.TryParse(v2.ToString(), out var parsed) && dateTimeOffset.Equals(parsed), - - _ => v1.Equals(v2) - }; + 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 { diff --git a/sdmap/test/sdmap.test/ValueComparerTests.cs b/sdmap/test/sdmap.test/ValueComparerTests.cs index be3430b..41b019a 100644 --- a/sdmap/test/sdmap.test/ValueComparerTests.cs +++ b/sdmap/test/sdmap.test/ValueComparerTests.cs @@ -5,89 +5,96 @@ namespace sdmap.test; +using static ComparisonResult; + public class ValueComparerTests { [Theory] - [MemberData(nameof(IsEqual_Cases_Number))] - [MemberData(nameof(IsEqual_Cases_Enum))] - [MemberData(nameof(IsEqual_Cases_Guid))] - [MemberData(nameof(IsEqual_Cases_Timespan))] - [MemberData(nameof(IsEqual_Cases_DateTime))] - public void IsEqual(object left, object right, bool areEqual) + [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.IsEqual(left, right); - Assert.Equal(areEqual, actual); + var actual = ValueComparer.Compare(left, right); + Assert.Equal(expected, actual); } - public static IEnumerable IsEqual_Cases_Number() + public static IEnumerable Compare_Cases_Number() { - yield return new object[] { 0, 0, true }; - yield return new object[] { 0, 0L, true }; - yield return new object[] { (short) 1, 1L, true }; - yield return new object[] { (byte) 1, (ulong) 1, true }; + yield return new object[] { 0, 0, AreEqual }; + yield return new object[] { 0, 0L, AreEqual }; + yield return new object[] { (short) 1, 1L, AreEqual }; + yield return new object[] { (byte) 1, (ulong) 1, AreEqual }; - yield return new object[] { 1D, 1F, true }; - yield return new object[] { 1M, 1M, true }; - yield return new object[] { 1M, 1D, true }; - yield return new object[] { 1M, 0D, false }; + yield return new object[] { 1D, 1F, AreEqual }; + yield return new object[] { 1M, 1M, AreEqual }; + yield return new object[] { 1M, 1D, AreEqual }; + yield return new object[] { 1M, 0D, LeftIsGreater }; - yield return new object[] { 1M, "1", true }; + yield return new object[] { 1M, "1", AreEqual }; } - public static IEnumerable IsEqual_Cases_Enum() + public static IEnumerable Compare_Cases_Enum() { - yield return new object[] { FirstEnum.One, FirstEnum.One, true }; - yield return new object[] { FirstEnum.One, FirstEnum.Two, false }; - yield return new object[] { FirstEnum.One, SecondEnum.One, false }; - yield return new object[] { FirstEnum.One, SecondEnum.Two, false }; + yield return new object[] { FirstEnum.One, FirstEnum.One, AreEqual }; + yield return new object[] { FirstEnum.One, FirstEnum.Two, LeftIsLess }; + yield return new object[] { FirstEnum.One, SecondEnum.One, Incomparable }; + yield return new object[] { FirstEnum.One, SecondEnum.Two, Incomparable }; - yield return new object[] { FirstEnum.One, 1, true }; - yield return new object[] { FirstEnum.One, "1", true }; - yield return new object[] { FirstEnum.One, "One", true }; - yield return new object[] { FirstEnum.One, 1.0M, false }; + yield return new object[] { FirstEnum.One, 1, AreEqual }; + yield return new object[] { FirstEnum.One, "1", AreEqual }; + yield return new object[] { FirstEnum.One, "One", AreEqual }; + yield return new object[] { FirstEnum.One, 1.0M, Incomparable }; } - public static IEnumerable IsEqual_Cases_Guid() + public static IEnumerable Compare_Cases_Guid() { yield return new object[] { new Guid("01d1692d-2221-47cd-892b-4a6552c6a9cc"), new Guid("01d1692d-2221-47cd-892b-4a6552c6a9cc"), - true + AreEqual }; yield return new object[] { new Guid("01d1692d-2221-47cd-892b-4a6552c6a9cc"), "01d1692d-2221-47cd-892b-4a6552c6a9cc", - true + AreEqual }; - yield return new object[] { Guid.NewGuid(), Guid.NewGuid(), false }; + yield return new object[] + { + new Guid("00000000-0000-0000-0000-000000000000"), + new Guid("11111111-0000-0000-0000-000000000000"), + LeftIsLess + }; yield return new object[] { new Guid("01d1692d-2221-47cd-892b-4a6552c6a9cc"), DateTime.Now, - false + Incomparable }; } - public static IEnumerable IsEqual_Cases_Timespan() + public static IEnumerable Compare_Cases_Timespan() { - yield return new object[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), true }; - yield return new object[] { TimeSpan.FromSeconds(1), "00:00:01", true }; - yield return new object[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(0), false }; - yield return new object[] { TimeSpan.FromSeconds(1), "10", false }; - yield return new object[] { TimeSpan.FromSeconds(1), DateTime.Now, false }; + yield return new object[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), AreEqual }; + yield return new object[] { TimeSpan.FromSeconds(1), "00:00:01", AreEqual }; + yield return new object[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(0), LeftIsGreater }; + yield return new object[] { TimeSpan.FromSeconds(1), "ten seconds", Incomparable }; + yield return new object[] { TimeSpan.FromSeconds(1), DateTime.Now, Incomparable }; } - public static IEnumerable IsEqual_Cases_DateTime() + public static IEnumerable Compare_Cases_DateTime() { - yield return new object[] { new DateTime(2023, 01, 01), new DateTime(2023, 01, 01), true }; - yield return new object[] { new DateTime(2023, 01, 01), new DateTime(1900, 01, 01), false }; - yield return new object[] { new DateTime(2023, 01, 01), "2023-01-01", true }; - yield return new object[] { DateTime.Now, TimeSpan.FromSeconds(0), false }; + yield return new object[] { new DateTime(2023, 01, 01), new DateTime(2023, 01, 01), AreEqual }; + yield return new object[] { new DateTime(2023, 01, 01), new DateTime(1900, 01, 01), LeftIsGreater }; + yield return new object[] { new DateTime(2023, 01, 01), "2023-01-01", AreEqual }; + yield return new object[] { DateTime.Now, "today", Incomparable }; } private enum FirstEnum { One = 1, Two = 2 } From b0573288366b59fd3f2403f1bd34e52937c79a22 Mon Sep 17 00:00:00 2001 From: zadykian Date: Wed, 30 Aug 2023 19:39:53 +0300 Subject: [PATCH 3/6] Used ValueCompared in following macros: isEqual, isNotEqual, isLessEqual, isLessThan, isGreaterEqual, isGreaterThan --- .../sdmap/Macros/Implements/RuntimeMacros.cs | 28 +++++++++++-------- .../sdmap/Macros/Implements/ValueComparer.cs | 9 +++--- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/sdmap/src/sdmap/Macros/Implements/RuntimeMacros.cs b/sdmap/src/sdmap/Macros/Implements/RuntimeMacros.cs index c6638e1..87f56d9 100644 --- a/sdmap/src/sdmap/Macros/Implements/RuntimeMacros.cs +++ b/sdmap/src/sdmap/Macros/Implements/RuntimeMacros.cs @@ -214,9 +214,10 @@ 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; @@ -233,9 +234,10 @@ 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; @@ -252,9 +254,10 @@ 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; @@ -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; diff --git a/sdmap/src/sdmap/Macros/Implements/ValueComparer.cs b/sdmap/src/sdmap/Macros/Implements/ValueComparer.cs index e189a14..8511ec8 100644 --- a/sdmap/src/sdmap/Macros/Implements/ValueComparer.cs +++ b/sdmap/src/sdmap/Macros/Implements/ValueComparer.cs @@ -5,13 +5,12 @@ namespace sdmap.Macros.Implements; -[Flags] public enum ComparisonResult : byte { - Incomparable = 1, - AreEqual = 2, - LeftIsGreater = 4, - LeftIsLess = 8 + Incomparable = 1, + AreEqual, + LeftIsGreater, + LeftIsLess } internal static class ValueComparer From b6ff8615022c85c7036c04251a6ca0eeb50eff96 Mon Sep 17 00:00:00 2001 From: zadykian Date: Wed, 30 Aug 2023 19:42:08 +0300 Subject: [PATCH 4/6] version: 0.16.4 -> 0.16.5 --- sdmap/src/sdmap.ext.Dapper/sdmap.ext.Dapper.csproj | 6 +++--- sdmap/src/sdmap.ext/sdmap.ext.csproj | 6 +++--- sdmap/src/sdmap/sdmap.csproj | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/sdmap/src/sdmap.ext.Dapper/sdmap.ext.Dapper.csproj b/sdmap/src/sdmap.ext.Dapper/sdmap.ext.Dapper.csproj index 796b482..2a64767 100644 --- a/sdmap/src/sdmap.ext.Dapper/sdmap.ext.Dapper.csproj +++ b/sdmap/src/sdmap.ext.Dapper/sdmap.ext.Dapper.csproj @@ -13,13 +13,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..7ba8802 100644 --- a/sdmap/src/sdmap.ext/sdmap.ext.csproj +++ b/sdmap/src/sdmap.ext/sdmap.ext.csproj @@ -13,13 +13,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/sdmap.csproj b/sdmap/src/sdmap/sdmap.csproj index 4488ec5..ddcc58b 100644 --- a/sdmap/src/sdmap/sdmap.csproj +++ b/sdmap/src/sdmap/sdmap.csproj @@ -14,9 +14,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 From 574ddb419b06dd6126288054c992d0975e0cc4e3 Mon Sep 17 00:00:00 2001 From: zadykian Date: Wed, 30 Aug 2023 21:18:02 +0300 Subject: [PATCH 5/6] GeneratePackageOnBuild = true --- sdmap/src/sdmap.ext.Dapper/sdmap.ext.Dapper.csproj | 1 + sdmap/src/sdmap.ext/sdmap.ext.csproj | 1 + sdmap/src/sdmap/sdmap.csproj | 1 + 3 files changed, 3 insertions(+) diff --git a/sdmap/src/sdmap.ext.Dapper/sdmap.ext.Dapper.csproj b/sdmap/src/sdmap.ext.Dapper/sdmap.ext.Dapper.csproj index 2a64767..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 diff --git a/sdmap/src/sdmap.ext/sdmap.ext.csproj b/sdmap/src/sdmap.ext/sdmap.ext.csproj index 7ba8802..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 diff --git a/sdmap/src/sdmap/sdmap.csproj b/sdmap/src/sdmap/sdmap.csproj index ddcc58b..166e4fc 100644 --- a/sdmap/src/sdmap/sdmap.csproj +++ b/sdmap/src/sdmap/sdmap.csproj @@ -7,6 +7,7 @@ sdmap sdmap dynamic sql;ibatis + true https://github.com/sdcb/sdmap/blob/master/ReleaseNotes.md git From 5ad6398c69032608c60d32efe201a70172c710e5 Mon Sep 17 00:00:00 2001 From: zadykian Date: Wed, 30 Aug 2023 22:01:58 +0300 Subject: [PATCH 6/6] changed comparand type from SdmapTypes.Number to Any for isLess/isGreater macros --- sdmap/src/sdmap/Macros/Implements/RuntimeMacros.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sdmap/src/sdmap/Macros/Implements/RuntimeMacros.cs b/sdmap/src/sdmap/Macros/Implements/RuntimeMacros.cs index 87f56d9..d6cfd77 100644 --- a/sdmap/src/sdmap/Macros/Implements/RuntimeMacros.cs +++ b/sdmap/src/sdmap/Macros/Implements/RuntimeMacros.cs @@ -204,7 +204,7 @@ public static Result IsNotEqual(OneCallContext context, } [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) { @@ -224,7 +224,7 @@ public static Result IsLessThan(OneCallContext context, } [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) { @@ -244,7 +244,7 @@ public static Result IsGreaterThan(OneCallContext context, } [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) { @@ -264,7 +264,7 @@ public static Result IsLessEqual(OneCallContext context, } [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) {