diff --git a/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Sql.Contracts/SqlDriverConfigDto.cs b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Sql.Contracts/SqlDriverConfigDto.cs new file mode 100644 index 00000000..fac5ee4c --- /dev/null +++ b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Sql.Contracts/SqlDriverConfigDto.cs @@ -0,0 +1,59 @@ +namespace ZB.MOM.WW.OtOpcUa.Driver.Sql.Contracts; + +/// +/// The DriverConfig blob shape for a Sql driver instance (design §5.1). Deserialised by the +/// driver factory, which applies the documented defaults for every absent (null) field and maps the result +/// onto the driver's typed options. +/// No connection string lives here. Only — a name resolved at +/// Initialize from the environment / secret store (e.g. Sql__ConnectionStrings__MesStaging) — so a +/// deployed artifact never carries database credentials. +/// Enum-valued fields are enum-typed (not strings) so a JsonStringEnumConverter round-trips +/// their names rather than their ordinals. The converter is applied by the factory's +/// JsonSerializerOptions (Task 9), not by an attribute on this DTO — mirroring the driver +/// enum-serialization trap that bit the AdminUI driver pages. +/// +public sealed class SqlDriverConfigDto +{ + /// Which ADO.NET provider/dialect backs this instance. Defaults to — the only provider v1 constructs. + public SqlProvider Provider { get; init; } = SqlProvider.SqlServer; + + /// + /// Name of the connection string to resolve from the environment / secret store at Initialize — + /// never the connection string itself. + /// + public string? ConnectionStringRef { get; init; } + + /// Poll interval applied to groups that do not carry their own. Absent ⇒ the factory default. + public TimeSpan? DefaultPollInterval { get; init; } + + /// + /// Per-query wall-clock deadline enforced client-side (a breach surfaces BadTimeout). Must be + /// greater than , which is only the server-side backstop (design §8.3). + /// + public TimeSpan? OperationTimeout { get; init; } + + /// ADO.NET CommandTimeout backstop (seconds granularity server-side). + public TimeSpan? CommandTimeout { get; init; } + + /// Cap on concurrently executing group queries — the connection-pool guard. + public int? MaxConcurrentGroups { get; init; } + + /// When , a NULL cell publishes Bad rather than the default Uncertain. + public bool? NullIsBad { get; init; } + + /// Master write kill-switch. v1 is read-only — writes stay disabled regardless. + public bool? AllowWrites { get; init; } + + /// Background connectivity-probe settings. Absent ⇒ the factory default. + public SqlProbeDto? Probe { get; init; } +} + +/// Background connectivity-probe settings inside a (design §5.1). +public sealed class SqlProbeDto +{ + /// Whether the driver runs its background connectivity probe. + public bool? Enabled { get; init; } + + /// Interval between probe attempts. + public TimeSpan? Interval { get; init; } +} diff --git a/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Sql.Contracts/SqlProvider.cs b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Sql.Contracts/SqlProvider.cs new file mode 100644 index 00000000..67879307 --- /dev/null +++ b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Sql.Contracts/SqlProvider.cs @@ -0,0 +1,39 @@ +namespace ZB.MOM.WW.OtOpcUa.Driver.Sql.Contracts; + +/// Which ADO.NET provider/dialect backs a Sql driver instance. v1 constructs only SqlServer. +public enum SqlProvider +{ + /// Microsoft SQL Server via Microsoft.Data.SqlClient — the only provider v1 constructs. + SqlServer, + + /// PostgreSQL (Npgsql) — reserved for P2; not constructed in v1. + Postgres, + + /// MySQL / MariaDB — reserved; not constructed in v1. + MySql, + + /// Generic ODBC — reserved for P2; not constructed in v1. + Odbc, + + /// Oracle — reserved; not constructed in v1. + Oracle, +} + +/// Tag→value mapping model. v1 ships KeyValue + WideRow; Query is deferred (design §5.4 / P3). +public enum SqlTagModel +{ + /// + /// Key-value (EAV) table: one row per tag, selected by keyColumn = keyValue, value read from + /// valueColumn. + /// + KeyValue, + + /// + /// Wide row: one row holds many signals as columns; the tag names its columnName and the row is + /// picked by a row selector (a whereColumn/whereValue pair, or newest-by-timestamp). + /// + WideRow, + + /// Named arbitrary-SELECT query (design §5.4). Deferred to P3 — not accepted by v1's parser. + Query, +}