87 lines
3.2 KiB
C#
87 lines
3.2 KiB
C#
using System;
|
|
using System.Text.RegularExpressions;
|
|
using TBF.Rig.Input.DataStorage.UniDataStorageWriter.Searching;
|
|
|
|
namespace TBF.Rig.Input.DataStorage.UniDataStorageWriter
|
|
{
|
|
/// <summary>
|
|
/// Parses SQL-like QueryTemplate expressions.
|
|
/// Supported syntax:
|
|
/// SELECT [ReturnColumn] WHERE [MatchColumn] = QUERYPARAM
|
|
/// SELECT COLUMN(1) WHERE COLUMN(0) = QUERYPARAM
|
|
/// Mixed forms are also supported.
|
|
/// </summary>
|
|
public static class SearchOrderParser
|
|
{
|
|
private static readonly Regex FullPattern = new Regex(
|
|
@"^\s*SELECT\s+(?<select>\[[^\]]+\]|COLUMN\(\d+\))\s+WHERE\s+(?<where>\[[^\]]+\]|COLUMN\(\d+\))\s*=\s*QUERYPARAM\s*$",
|
|
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
|
|
|
private static readonly Regex NamedColumnPattern = new Regex(
|
|
@"^\[(?<name>[^\]]+)\]$",
|
|
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
|
|
|
private static readonly Regex IndexedColumnPattern = new Regex(
|
|
@"^COLUMN\((?<index>\d+)\)$",
|
|
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
|
|
|
/// <summary>
|
|
/// Parses QueryTemplate text into structured definition.
|
|
/// Throws if syntax is invalid.
|
|
/// </summary>
|
|
public static SearchOrderDefinition Parse(string searchOrder)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(searchOrder))
|
|
throw new InvalidOperationException("QueryTemplate is empty.");
|
|
|
|
Match match = FullPattern.Match(searchOrder);
|
|
if (!match.Success)
|
|
{
|
|
throw new InvalidOperationException(
|
|
"Invalid QueryTemplate syntax. Expected: SELECT [ReturnColumn] WHERE [MatchColumn] = QUERYPARAM");
|
|
}
|
|
|
|
string selectToken = match.Groups["select"].Value;
|
|
string whereToken = match.Groups["where"].Value;
|
|
|
|
return new SearchOrderDefinition
|
|
{
|
|
SelectColumn = ParseColumnReference(selectToken),
|
|
WhereColumn = ParseColumnReference(whereToken)
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Parses one column reference token:
|
|
/// [ColumnName] or COLUMN(number)
|
|
/// </summary>
|
|
private static ColumnReference ParseColumnReference(string token)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(token))
|
|
throw new InvalidOperationException("Column reference token is empty.");
|
|
|
|
Match nameMatch = NamedColumnPattern.Match(token);
|
|
if (nameMatch.Success)
|
|
{
|
|
return new ColumnReference
|
|
{
|
|
Name = nameMatch.Groups["name"].Value.Trim(),
|
|
Index = null
|
|
};
|
|
}
|
|
|
|
Match indexMatch = IndexedColumnPattern.Match(token);
|
|
if (indexMatch.Success)
|
|
{
|
|
return new ColumnReference
|
|
{
|
|
Name = null,
|
|
Index = int.Parse(indexMatch.Groups["index"].Value)
|
|
};
|
|
}
|
|
|
|
throw new InvalidOperationException(
|
|
"Invalid column reference '" + token + "'. Use [ColumnName] or COLUMN(number).");
|
|
}
|
|
}
|
|
} |