using System.Globalization;
using System.Text.RegularExpressions;
namespace Admin.NET.Plugin.AiDOP.DataPlatform.Executors;
///
/// P-015:解析调度同步窗口(FULL / INCR / ROLLING),供抽数 SQL 使用。
///
public static class MdpSyncWindowResolver
{
private static readonly Regex DurationRegex = new(
@"^\s*(?\d+)\s*(?[dDhHmM])\s*$",
RegexOptions.Compiled);
///
/// 将窗口类型落到上下文:FULL→全量;INCR→水位;ROLLING→下界时间。
/// 显式 FullRefresh 时强制 FULL。
///
public static void Apply(MdpPullContext ctx)
{
if (ctx.FullRefresh)
{
ctx.SyncWindowType = "FULL";
ctx.WindowFrom = null;
return;
}
var type = (ctx.SyncWindowType ?? "INCR").Trim().ToUpperInvariant();
if (type is "ROLLING_WINDOW") type = "ROLLING";
switch (type)
{
case "FULL":
ctx.SyncWindowType = "FULL";
ctx.FullRefresh = true;
ctx.WindowFrom = null;
break;
case "ROLLING":
ctx.SyncWindowType = "ROLLING";
ctx.WindowFrom = ResolveWindowFrom(ctx.SyncWindowValue, DateTime.Now)
?? DateTime.Now.AddDays(-7);
break;
default:
// INCR / 其它:走 last_cursor
ctx.SyncWindowType = "INCR";
ctx.WindowFrom = null;
break;
}
}
///
/// 解析窗口参数:支持 7d/24h/30m 或绝对时间 yyyy-MM-dd[ HH:mm:ss]。
///
public static DateTime? ResolveWindowFrom(string? value, DateTime now)
{
if (string.IsNullOrWhiteSpace(value)) return null;
var raw = value.Trim();
var m = DurationRegex.Match(raw);
if (m.Success)
{
var n = int.Parse(m.Groups["n"].Value, CultureInfo.InvariantCulture);
return m.Groups["u"].Value.ToUpperInvariant() switch
{
"D" => now.AddDays(-n),
"H" => now.AddHours(-n),
"M" => now.AddMinutes(-n),
_ => null
};
}
if (DateTime.TryParse(raw, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out var abs)
|| DateTime.TryParse(raw, CultureInfo.CurrentCulture, DateTimeStyles.AssumeLocal, out abs))
return abs;
return null;
}
}