2022-06-03 23:07:44 +08:00
|
|
|
using System.Collections.ObjectModel;
|
|
|
|
using System.Reflection;
|
|
|
|
using ShardingCore.Core.EntityMetadatas;
|
|
|
|
using ShardingCore.Core.VirtualRoutes;
|
|
|
|
using ShardingCore.Helpers;
|
|
|
|
using ShardingCore.Utils;
|
|
|
|
using Xunit;
|
|
|
|
|
|
|
|
namespace ShardingCore.CommonTest
|
|
|
|
{
|
2022-07-02 22:19:24 +08:00
|
|
|
|
2022-08-03 23:12:47 +08:00
|
|
|
|
2022-06-03 23:07:44 +08:00
|
|
|
public class ShardingTableTime
|
|
|
|
{
|
|
|
|
private readonly EntityMetadata _testEntityMetadata;
|
|
|
|
private readonly List<string> _allTables;
|
|
|
|
public ShardingTableTime()
|
|
|
|
{
|
2022-07-01 20:58:20 +08:00
|
|
|
var entityMetadata = new EntityMetadata(typeof(TestTimeEntity));
|
2022-06-03 23:07:44 +08:00
|
|
|
var entityMetadataTableBuilder = EntityMetadataTableBuilder<TestTimeEntity>.CreateEntityMetadataTableBuilder(entityMetadata);
|
|
|
|
entityMetadataTableBuilder.ShardingProperty(o => o.Time);
|
|
|
|
entityMetadata.CheckShardingTableMetadata();
|
|
|
|
_testEntityMetadata = entityMetadata;
|
|
|
|
var dateTime = new DateTime(2022,1,1);
|
|
|
|
//[20220101....20220120]
|
|
|
|
_allTables = Enumerable.Range(0,20).Select(o=>dateTime.AddDays(o).ToString("yyyyMMdd")).ToList();
|
|
|
|
}
|
|
|
|
public static Func<string, bool> GetRouteFilter(object shardingValue, ShardingOperatorEnum shardingOperator,
|
|
|
|
string propertyName)
|
|
|
|
{
|
|
|
|
if (propertyName != nameof(TestTimeEntity.Time))
|
|
|
|
{
|
|
|
|
throw new Exception($"{nameof(propertyName)}:[{propertyName}] error");
|
|
|
|
}
|
|
|
|
|
|
|
|
var shardingKey = (DateTime)shardingValue;
|
|
|
|
var t =$"{shardingKey:yyyyMMdd}";
|
|
|
|
switch (shardingOperator)
|
|
|
|
{
|
|
|
|
case ShardingOperatorEnum.GreaterThan:
|
|
|
|
case ShardingOperatorEnum.GreaterThanOrEqual:
|
|
|
|
return tail =>String.Compare(tail, t, StringComparison.Ordinal) >= 0;
|
|
|
|
case ShardingOperatorEnum.LessThan:
|
|
|
|
{
|
|
|
|
var shardingKeyDate = shardingKey.Date;
|
|
|
|
//处于临界值 o=>o.time < [2021-01-01 00:00:00] 尾巴20210101不应该被返回
|
|
|
|
if (shardingKeyDate == shardingKey)
|
|
|
|
return tail =>String.Compare(tail, t, StringComparison.Ordinal) < 0;
|
|
|
|
return tail =>String.Compare(tail, t, StringComparison.Ordinal) <= 0;
|
|
|
|
}
|
|
|
|
case ShardingOperatorEnum.LessThanOrEqual:
|
|
|
|
return tail =>String.Compare(tail, t, StringComparison.Ordinal) <= 0;
|
|
|
|
case ShardingOperatorEnum.Equal: return tail => tail == t;
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
return tail => true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void TestId(IQueryable<TestTimeEntity> queryable, string[] tables)
|
|
|
|
{
|
2022-07-18 23:52:11 +08:00
|
|
|
var routePredicateExpression = ShardingUtil.GetRouteParseExpression(queryable,_testEntityMetadata,GetRouteFilter,true);
|
2022-06-03 23:07:44 +08:00
|
|
|
Assert.NotNull(routePredicateExpression);
|
|
|
|
var routePredicate = routePredicateExpression.GetRoutePredicate();
|
|
|
|
|
|
|
|
var list = _allTables.Where(routePredicate).ToList();
|
|
|
|
Assert.NotNull(list);
|
|
|
|
Assert.Equal(tables.Length,list.Count);
|
|
|
|
foreach (var table in tables)
|
|
|
|
{
|
|
|
|
Assert.True(list.Any(o=>o==table));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void TestFor(List<IQueryable<TestTimeEntity>> queryables, string[] tables)
|
|
|
|
{
|
|
|
|
foreach (var queryable in queryables)
|
|
|
|
{
|
|
|
|
TestId(queryable, tables);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
[Fact]
|
|
|
|
public void TestSingleTable()
|
|
|
|
{
|
|
|
|
var queryTime = new DateTime(2022, 1, 2);
|
|
|
|
var queryTime1 = queryTime.AddHours(1);
|
|
|
|
var queryTime2 = new DateTime(2022, 1, 3);
|
|
|
|
var queryTime3 = new DateTime(2022, 1, 3).AddSeconds(-1);
|
|
|
|
var table = queryTime.ToString("yyyyMMdd");
|
|
|
|
var tables = new []{table};
|
|
|
|
var id = "1";
|
|
|
|
var times = new []{queryTime};
|
|
|
|
var times1 = new List<DateTime>(){queryTime};
|
2022-07-18 23:30:05 +08:00
|
|
|
var times2 = new []{queryTime,queryTime2};
|
2022-06-03 23:07:44 +08:00
|
|
|
var obj1 = new {time=new DateTime(2022, 1, 2)};
|
|
|
|
var queryables=new List<IQueryable<TestTimeEntity>>()
|
|
|
|
{
|
2022-08-03 23:12:47 +08:00
|
|
|
new List<TestTimeEntity>().AsQueryable().CheckBetween((DateTime?)queryTime,(DateTime?)queryTime3,o=>o.Time),
|
2022-07-18 23:30:05 +08:00
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time==times2[0]),
|
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time>=times2[0]&&o.Time<times2[1]),
|
2022-07-18 23:08:48 +08:00
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time>=queryTime&&o.Time<queryTime2),
|
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time==queryTime),
|
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time>=queryTime&&o.Time<queryTime2),
|
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time>=queryTime&&o.Time<queryTime3),
|
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time>=queryTime&&o.Time<=queryTime3),
|
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time==queryTime1),
|
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>queryTime==o.Time),
|
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time.Equals(queryTime)),
|
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>queryTime.Equals(o.Time)),
|
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time==obj1.time),
|
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time.Equals(obj1.time)),
|
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>obj1.time.Equals(o.Time)),
|
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>times.Contains(o.Time)),
|
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>new []{queryTime}.Contains(o.Time)),
|
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>times1.Contains(o.Time)),
|
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=> new List<DateTime>(){queryTime}.Contains(o.Time))
|
2022-06-03 23:07:44 +08:00
|
|
|
};
|
|
|
|
TestFor(queryables,tables);
|
|
|
|
}
|
|
|
|
//[20220101....20220120]
|
|
|
|
[Fact]
|
|
|
|
public void TestMultiTable()
|
|
|
|
{
|
|
|
|
var tables = new []{"20220101","20220102","20220119","20220120"};
|
|
|
|
var begin = new DateTime(2022,01,03);
|
|
|
|
var begin1 = new DateTime(2022,01,02);
|
|
|
|
var end1 = new DateTime(2022,01,19);
|
|
|
|
var begin2 = new DateTime(2022,01,01);
|
|
|
|
var end2 = new DateTime(2022,01,20);
|
|
|
|
var queryables=new List<IQueryable<TestTimeEntity>>()
|
|
|
|
{
|
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time<begin||o.Time>=end1),
|
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>begin>o.Time||end1<=o.Time),
|
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time<=begin1||o.Time>=end1),
|
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>begin1>=o.Time||o.Time>=end1),
|
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>begin1>=o.Time||end1<=o.Time),
|
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>(o.Time>=begin2&&o.Time<=begin1)||(o.Time>=end1&&o.Time<=end2)),
|
|
|
|
};
|
|
|
|
TestFor(queryables,tables);
|
|
|
|
}
|
|
|
|
[Fact]
|
|
|
|
public void TestMultiTable1()
|
|
|
|
{
|
|
|
|
var tables = new []{"20220105","20220106","20220107"};
|
|
|
|
var time1 = new DateTime(2022,01,05);
|
|
|
|
var time2 = new DateTime(2022,01,07);
|
|
|
|
var time3 = new DateTime(2022,01,08);
|
|
|
|
var time4 = new DateTime(2022,01,06);
|
|
|
|
var dateTimes = new []{time1,time2,time4};
|
|
|
|
var queryables=new List<IQueryable<TestTimeEntity>>()
|
|
|
|
{
|
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time>=time1&&o.Time<=time2),
|
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time<=time2&&o.Time>=time1),
|
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time>=time1.AddHours(1)&&o.Time<=time2),
|
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time>=time1&&o.Time<time2.AddHours(1)),
|
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time>=time1&&o.Time<time3),
|
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time>=time1&&o.Time<=time3.AddHours(-1)),
|
|
|
|
new List<TestTimeEntity>().AsQueryable().Where(o=>dateTimes.Contains(o.Time)),
|
|
|
|
};
|
|
|
|
TestFor(queryables,tables);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
public class TestTimeEntity
|
|
|
|
{
|
|
|
|
public string Id { get; set; }
|
|
|
|
public DateTime Time { get; set; }
|
|
|
|
}
|
|
|
|
}
|