123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Reflection;
- using System.Text;
- using System.Text.RegularExpressions;
- using System.Threading.Tasks;
- namespace SqlSugar
- {
- public class DateSplitTableService : ISplitTableService
- {
- #region Core
- public virtual List<SplitTableInfo> GetAllTables(ISqlSugarClient db, EntityInfo EntityInfo, List<DbTableInfo> tableInfos)
- {
- CheckTableName(EntityInfo.DbTableName);
- var regex = "^"+EntityInfo.DbTableName.Replace("{year}", "([0-9]{2,4})").Replace("{day}", "([0-9]{1,2})").Replace("{month}", "([0-9]{1,2})");
- var currentTables = tableInfos.Where(it => Regex.IsMatch(it.Name, regex, RegexOptions.IgnoreCase)).Select(it => it.Name).Reverse().ToList();
- List<SplitTableInfo> result = new List<SplitTableInfo>();
- foreach (var item in currentTables)
- {
- SplitTableInfo tableInfo = new SplitTableInfo();
- tableInfo.TableName = item;
- var math = Regex.Match(item, regex,RegexOptions.IgnoreCase);
- var group1 = math.Groups[1].Value;
- var group2 = math.Groups[2].Value;
- var group3 = math.Groups[3].Value;
- tableInfo.Date = GetDate(group1, group2, group3, EntityInfo.DbTableName);
- //tableInfo.String = null; Time table, it doesn't work
- //tableInfo.Long = null; Time table, it doesn't work
- result.Add(tableInfo);
- }
- result = result.OrderByDescending(it => it.Date).ToList();
- return result;
- }
- public virtual string GetTableName(ISqlSugarClient db, EntityInfo EntityInfo)
- {
- var splitTableAttribute = EntityInfo.Type.GetCustomAttribute<SplitTableAttribute>();
- if (splitTableAttribute != null)
- {
- var type=(splitTableAttribute as SplitTableAttribute).SplitType;
- return GetTableName(db, EntityInfo, type);
- }
- else
- {
- return GetTableName(db, EntityInfo, SplitType.Day);
- }
- }
- public virtual string GetTableName(ISqlSugarClient db, EntityInfo EntityInfo, SplitType splitType)
- {
- var date = db.GetDate();
- return GetTableNameByDate(EntityInfo, splitType, date);
- }
- public virtual string GetTableName(ISqlSugarClient db, EntityInfo entityInfo, SplitType splitType, object fieldValue)
- {
- var value = Convert.ToDateTime(fieldValue);
- return GetTableNameByDate(entityInfo, splitType, value);
- }
- public virtual object GetFieldValue(ISqlSugarClient db, EntityInfo entityInfo, SplitType splitType, object entityValue)
- {
- var splitColumn = entityInfo.Columns.FirstOrDefault(it => it.PropertyInfo.GetCustomAttribute<SplitFieldAttribute>() != null);
- if (splitColumn == null)
- {
- return db.GetDate();
- }
- else
- {
- if (entityValue == null)
- {
- return null;
- }
- var value = splitColumn.PropertyInfo.GetValue(entityValue, null);
- if (value == null)
- {
- return db.GetDate();
- }
- else if (value is DateTimeOffset)
- {
- return ((DateTimeOffset)value).DateTime;
- }
- else if (UtilMethods.GetUnderType(value.GetType()) != UtilConstants.DateType)
- {
- throw new Exception($"DateSplitTableService Split column {splitColumn.PropertyName} not DateTime " + splitType.ToString());
- }
- else if (Convert.ToDateTime(value) == DateTime.MinValue)
- {
- return db.GetDate();
- }
- else
- {
- return value;
- }
- }
- }
- public void VerifySplitType(SplitType splitType)
- {
- switch (splitType)
- {
- case SplitType.Day:
- break;
- case SplitType.Week:
- break;
- case SplitType.Month:
- break;
- case SplitType.Season:
- break;
- case SplitType.Year:
- break;
- case SplitType.Month_6:
- break;
- default:
- throw new Exception("DateSplitTableService no support " + splitType.ToString());
- }
- }
- #endregion
- #region Common Helper
- private string GetTableNameByDate(EntityInfo EntityInfo,SplitType splitType,DateTime date)
- {
- date = ConvertDateBySplitType(date, splitType);
- return EntityInfo.DbTableName.Replace("{year}", date.Year + "").Replace("{day}", PadLeft2(date.Day + "")).Replace("{month}", PadLeft2(date.Month + ""));
- }
- private DateTime GetDate(string group1, string group2, string group3, string dbTableName)
- {
- var yearIndex = dbTableName.IndexOf("{year}");
- var dayIndex = dbTableName.IndexOf("{day}");
- var monthIndex = dbTableName.IndexOf("{month}");
- List<SplitTableSort> tables = new List<SplitTableSort>();
- tables.Add(new SplitTableSort() { Name = "{year}", Sort = yearIndex });
- tables.Add(new SplitTableSort() { Name = "{day}", Sort = dayIndex });
- tables.Add(new SplitTableSort() { Name = "{month}", Sort = monthIndex });
- tables = tables.OrderBy(it => it.Sort).ToList();
- var year = "";
- var month = "";
- var day = "";
- if (tables[0].Name == "{year}")
- {
- year = group1;
- }
- if (tables[1].Name == "{year}")
- {
- year = group2;
- }
- if (tables[2].Name == "{year}")
- {
- year = group3;
- }
- if (tables[0].Name == "{month}")
- {
- month = group1;
- }
- if (tables[1].Name == "{month}")
- {
- month = group2;
- }
- if (tables[2].Name == "{month}")
- {
- month = group3;
- }
- if (tables[0].Name == "{day}")
- {
- day = group1;
- }
- if (tables[1].Name == "{day}")
- {
- day = group2;
- }
- if (tables[2].Name == "{day}")
- {
- day = group3;
- }
- return Convert.ToDateTime($"{year}-{month}-{day}");
- }
- private string PadLeft2(string str)
- {
- if (str.Length < 2)
- {
- return str.PadLeft(2, '0');
- }
- else
- {
- return str;
- }
- }
- private static void CheckTableName(string dbTableName)
- {
- Check.Exception(!dbTableName.Contains("{year}"), ErrorMessage.GetThrowMessage("table name need {{year}}", "分表表名需要占位符 {{year}}"));
- Check.Exception(!dbTableName.Contains("{month}"), ErrorMessage.GetThrowMessage("table name need {{month}}", "分表表名需要占位符 {{month}} "));
- Check.Exception(!dbTableName.Contains("{day}"), ErrorMessage.GetThrowMessage("table name need {{day}}", "分表表名需要占位符{{day}}"));
- Check.Exception(Regex.Matches(dbTableName, @"\{year\}").Count > 1, ErrorMessage.GetThrowMessage(" There can only be one {{year}}", " 只能有一个 {{year}}"));
- Check.Exception(Regex.Matches(dbTableName, @"\{month\}").Count > 1, ErrorMessage.GetThrowMessage("There can only be one {{month}}", "只能有一个 {{month}} "));
- Check.Exception(Regex.Matches(dbTableName, @"\{day\}").Count > 1, ErrorMessage.GetThrowMessage("There can only be one {{day}}", "只能有一个{{day}}"));
- Check.Exception(Regex.IsMatch(dbTableName, @"\d\{|\}\d"), ErrorMessage.GetThrowMessage(" '{{' or '}}' can't be numbers nearby", "占位符相令一位不能是数字,比如 : 1{{day}}2 错误 , 正确: 1_{{day}}_2"));
- }
- #endregion
- #region Date Helper
- private DateTime ConvertDateBySplitType(DateTime time, SplitType type)
- {
- switch (type)
- {
- case SplitType.Day:
- return Convert.ToDateTime(time.ToString("yyyy-MM-dd"));
- case SplitType.Week:
- return GetMondayDate(time);
- case SplitType.Month:
- return Convert.ToDateTime(time.ToString("yyyy-MM-01"));
- case SplitType.Season:
- if (time.Month <= 3)
- {
- return Convert.ToDateTime(time.ToString("yyyy-01-01"));
- }
- else if (time.Month <= 6)
- {
- return Convert.ToDateTime(time.ToString("yyyy-04-01"));
- }
- else if (time.Month <= 9)
- {
- return Convert.ToDateTime(time.ToString("yyyy-07-01"));
- }
- else
- {
- return Convert.ToDateTime(time.ToString("yyyy-10-01"));
- }
- case SplitType.Year:
- return Convert.ToDateTime(time.ToString("yyyy-01-01"));
- case SplitType.Month_6:
- if (time.Month <= 6)
- {
- return Convert.ToDateTime(time.ToString("yyyy-01-01"));
- }
- else
- {
- return Convert.ToDateTime(time.ToString("yyyy-07-01"));
- }
- default:
- throw new Exception($"SplitType parameter error ");
- }
- }
- private DateTime GetMondayDate()
- {
- return GetMondayDate(DateTime.Now);
- }
- private DateTime GetSundayDate()
- {
- return GetSundayDate(DateTime.Now);
- }
- private DateTime GetMondayDate(DateTime someDate)
- {
- int i = someDate.DayOfWeek - DayOfWeek.Monday;
- if (i == -1) i = 6;
- TimeSpan ts = new TimeSpan(i, 0, 0, 0);
- return someDate.Subtract(ts);
- }
- private DateTime GetSundayDate(DateTime someDate)
- {
- int i = someDate.DayOfWeek - DayOfWeek.Sunday;
- if (i != 0) i = 7 - i;
- TimeSpan ts = new TimeSpan(i, 0, 0, 0);
- return someDate.Add(ts);
- }
- #endregion
- #region Private Models
- internal class SplitTableSort
- {
- public string Name { get; set; }
- public int Sort { get; set; }
- }
- #endregion
- }
- }
|