namespace ZB.MOM.WW.OtOpcUa.Driver.Sql.Contracts;
///
/// The keys SqlBrowseSession states in a browsed column's AttributeInfo.AddressFields, and
/// that RawBrowseCommitMapper reads back when it builds the committed tag's TagConfig.
/// Why a shared constant rather than a literal at each end. A Sql tag's binding is a tuple
/// (table + column + which row), so — exactly as for MQTT's Sparkplug tuple and
/// MqttTagConfigKeys — the producing session states the parts and the mapper must never
/// re-infer them. Two independently spelled string literals agree by coincidence, and a disagreement is
/// silent: the mapper simply sees no field, and emits a config missing whatever the session was trying
/// to say. That is precisely how Gitea #552 shipped — a wide-row blob with no rowSelector, which
/// both and the authoring gate refuse.
/// These are the browse channel's names, not the tag blob's schema. Three of them happen
/// to match a TagConfig key because the mapper writes them straight through;
/// matches the key nested inside rowSelector — deliberately
/// not spelled timestampColumn, which is the blob's unrelated top-level source-timestamp
/// field.
///
public static class SqlBrowseAddressFields
{
/// The catalog schema owning the browsed column's table (e.g. dbo, sales).
public const string Schema = "schema";
/// The unqualified table (or view) name the browsed column belongs to.
public const string Table = "table";
/// The browsed column's own name — the wide-row tag's value column.
public const string ColumnName = "columnName";
///
/// The table's preferred date/time-typed column, when it has one: the commit writes it as the
/// wide-row rowSelector.topByTimestamp, i.e. "read the newest row". Absent when the table
/// carries no date/time column at all, which is not a shape a browse can bind — see
/// RawBrowseCommitMapper.DescribeUncommittableLeaf.
///
public const string TopByTimestamp = "topByTimestamp";
}