v10.10.2024.0601 优化Json序列化,支持DateOnly/TimeOnly,支持带时区的时间序列化
石头 编写于 2024-06-01 08:10:50
X
using System;
using System.Collections.Generic;
using NewLife;

namespace XCode.DataAccessLayer
{
    /// <summary>时间区间</summary>
    public struct TimeRegion
    {
        /// <summary>开始时间</summary>
        public TimeSpan Start;

        /// <summary>结束时间</summary>
        public TimeSpan End;
    }

    /// <summary>读写分离策略。忽略时间区间和表名</summary>
    public class ReadWriteStrategy
    {
        /// <summary>要忽略的时间区间</summary>
        public IList<TimeRegion> IgnoreTimes { get; set; } = new List<TimeRegion>();

        /// <summary>要忽略的表名</summary>
        public ICollection<String> IgnoreTables { get; set; } = new HashSet<String>(StringComparer.OrdinalIgnoreCase);

        /// <summary>设置不走读写分离的时间段,如00:30-00:50,多段区间逗号分开</summary>
        /// <param name="regions"></param>
        public void AddIgnoreTimes(String regions)
        {
            var rs = regions.Split(',', StringSplitOptions.RemoveEmptyEntries);
            foreach (var item in rs)
            {
                var ss = item.Split('-');
                if (ss.Length == 2)
                {
                    if (TimeSpan.TryParse(ss[0], out var start) &&
                        TimeSpan.TryParse(ss[1], out var end) &&
                        start < end)
                    {
                        IgnoreTimes.Add(new TimeRegion { Start = start, End = end });
                    }
                }
            }
        }

        /// <summary>检查是否支持读写分离</summary>
        /// <param name="dal"></param>
        /// <param name="sql"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        public virtual Boolean Validate(DAL dal, String sql, String action)
        {
            // 事务中不支持分离
            if (dal.ReadOnly == null) return false;
            if (dal.Session.Transaction != null) return false;

            if (!action.EqualIgnoreCase("Select", "SelectCount", "Query")) return false;
            if (action == "ExecuteScalar" && !sql.TrimStart().StartsWithIgnoreCase("select ")) return false;

            // 判断是否忽略的时间区间
            var span = DateTime.Now - DateTime.Today;
            foreach (var item in IgnoreTimes)
            {
                if (span >= item.Start && span < item.End) return false;
            }

            // 是否忽略的表名
            if (!sql.IsNullOrEmpty())
            {
                var tables = DAL.GetTables(sql);
                foreach (var item in tables)
                {
                    if (IgnoreTables.Contains(item)) return false;
                }
            }

            return true;
        }
    }
}