fix(sql): read keyValue with the same scalar read as whereValue (Driver.Sql.Contracts-001)
The two value-bearing fields were read asymmetrically and nothing said why. whereValue went through ReadScalar (string/number/boolean — the design doc's own wide-row example authors it as the number 7); keyValue went through the string-only ReadString, so a numerically-authored key refused the tag outright. Nothing downstream justified the split: both are BOUND as DbParameters and both are matched back as text — SqlPollReader.IndexByKey stringifies the key cell precisely so an authored key can face an INTEGER key column. The refusal was also mis-explained. Inspect branched on ReadString(root, "keyValue") is null, so a numerically-authored key drew "Sql KeyValue tag has no 'keyValue'" — telling the operator the field is missing when it is right there in the blob, the #549 shape of an authoring surface disagreeing with the runtime about WHY. keyValue now uses ReadScalar; Inspect mirrors it with HasScalar and says what a usable key is; SqlTagConfigModel loads it with the shared TagConfigJson.GetScalarText (which also replaces SqlRowSelectorModel's private copy), so the editor is not left stricter than the parser. An object/array/null key is still refused. docs/drivers/Sql.md updated. RED first: 4 failing in Driver.Sql.Tests.
This commit is contained in:
@@ -184,6 +184,32 @@ public sealed class SqlTagConfigModelTests
|
||||
=> SqlTagConfigModel.FromJson("""{"model":"KeyValue","table":"t","keyColumn":"k","valueColumn":"c"}""")
|
||||
.Validate().ShouldNotBeNull();
|
||||
|
||||
/// <summary>
|
||||
/// Driver.Sql.Contracts-001. The parser reads <c>keyValue</c> with the same scalar read it uses for
|
||||
/// <c>whereValue</c>, so a numerically-authored key is SERVED — the editor must load it (rather
|
||||
/// than seeing an absent key), let it save, and normalise it to a string on the way out, exactly as
|
||||
/// it already does for <c>whereValue</c>. An editor that refused it would be stricter than the
|
||||
/// runtime, which is the drift this parity suite exists to catch.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void A_numerically_authored_keyValue_loads_validates_and_normalises_to_a_string()
|
||||
{
|
||||
const string json =
|
||||
"""{"model":"KeyValue","table":"t","keyColumn":"station_id","keyValue":7,"valueColumn":"c"}""";
|
||||
SqlEquipmentTagParser.TryParse(json, "raw", out var served).ShouldBeTrue(
|
||||
"the runtime must serve this blob, or the authoring parity below proves nothing.");
|
||||
served.KeyValue.ShouldBe("7");
|
||||
|
||||
var m = SqlTagConfigModel.FromJson(json);
|
||||
m.KeyValue.ShouldBe("7");
|
||||
m.Validate().ShouldBeNull();
|
||||
|
||||
var saved = m.ToJson();
|
||||
saved.ShouldContain("\"keyValue\":\"7\"");
|
||||
SqlEquipmentTagParser.TryParse(saved, "raw", out var afterSave).ShouldBeTrue();
|
||||
afterSave.KeyValue.ShouldBe("7");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Validate_rejects_wideRow_without_a_selector()
|
||||
=> SqlTagConfigModel.FromJson("""{"model":"WideRow","table":"t","columnName":"c"}""")
|
||||
|
||||
Reference in New Issue
Block a user