Skip to content

Commit 64f28dc

Browse files
authored
[MCP]Fixed CLI bug in fields.primary-key updation when using update entity command. (#3077)
## Why make this change? When updating an entity with a command like: `dab update Incident --fields.name "Id" --fields.description "Unique Key"`, the existing `primary-key` flag on Id was being changed to `false`even though no `primary-key` option was specified. This change removes that surprise so primary-key metadata only changes when explicitly requested. ## What is this change? - Adjusts the entity update logic so that: 1. If the user does not provide any fields.primary-key option, existing primary-key flags for fields mentioned in fields.name are preserved. 2. If the user does provide fields.primary-key, those true/false values are still applied positionally to the corresponding fields exactly as before. - Adds a regression test that: 1. Starts from a config where Id is already a primary key. 2. Runs an update that only changes the description for Id via `fields.name` and `fields.description`. 3. Verifies that the description changes and the primary-key flag on Id remains true. ## How was this tested? - [ ] Integration Tests - [x] Unit Tests 1. Existing CLI unit tests for entity update. 2. New regression test that validates `primary-key` is preserved when only the field description is updated. ## Sample Request(s) - To demonstrate the fixed behavior: 1. Initial state: Id is configured as a primary key on the entity. 2. Command: `dab update Incident --fields.name "Id" --fields.description "Unique Key 2"` 3. Result after this change: 4. The description for Id becomes “Unique Key 2”. 5. The primary-key flag for Id stays true. - To explicitly change primary keys (still supported): 1. Set Id as primary key: ` dab update Incident --fields.name "Id" --fields.primary-key true` 2. Clear Id as primary key: `dab update Incident --fields.name "Id" --fields.primary-key false`
1 parent 9025bb3 commit 64f28dc

2 files changed

Lines changed: 91 additions & 1 deletion

File tree

src/Cli.Tests/UpdateEntityTests.cs

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,6 +1100,92 @@ public void TestUpdateEntityDescription()
11001100
Assert.AreEqual("Updated description", updatedRuntimeConfig.Entities["MyEntity"].Description);
11011101
}
11021102

1103+
/// <summary>
1104+
/// Updating a field's description should either preserve or clear
1105+
/// the existing primary-key flag depending on whether an explicit
1106+
/// --fields.primary-key value is provided.
1107+
/// </summary>
1108+
[DataTestMethod]
1109+
[DataRow(null, true, DisplayName = "No primary-key flag: preserve existing true")]
1110+
[DataRow(false, false, DisplayName = "Explicit primary-key false: clear existing true")]
1111+
public void TestUpdateFieldDescriptionPrimaryKeyBehavior(bool? primaryKeyFlag, bool expectedPrimaryKey)
1112+
{
1113+
string initialConfig = GetInitialConfigString() + "," + @"
1114+
""entities"": {
1115+
""MyEntity"": {
1116+
""source"": ""MyTable"",
1117+
""fields"": [
1118+
{
1119+
""name"": ""Id"",
1120+
""description"": ""Primary key"",
1121+
""primary-key"": true
1122+
}
1123+
],
1124+
""permissions"": [
1125+
{
1126+
""role"": ""anonymous"",
1127+
""actions"": [""read""]
1128+
}
1129+
]
1130+
}
1131+
}
1132+
}";
1133+
1134+
IEnumerable<bool>? primaryKeyFlags = primaryKeyFlag.HasValue
1135+
? new[] { primaryKeyFlag.Value }
1136+
: null;
1137+
1138+
UpdateOptions options = new(
1139+
source: null,
1140+
permissions: null,
1141+
entity: "MyEntity",
1142+
sourceType: null,
1143+
sourceParameters: null,
1144+
sourceKeyFields: null,
1145+
restRoute: null,
1146+
graphQLType: null,
1147+
fieldsToInclude: null,
1148+
fieldsToExclude: null,
1149+
policyRequest: null,
1150+
policyDatabase: null,
1151+
relationship: null,
1152+
cardinality: null,
1153+
targetEntity: null,
1154+
linkingObject: null,
1155+
linkingSourceFields: null,
1156+
linkingTargetFields: null,
1157+
relationshipFields: null,
1158+
map: null,
1159+
cacheEnabled: null,
1160+
cacheTtl: null,
1161+
config: TEST_RUNTIME_CONFIG_FILE,
1162+
restMethodsForStoredProcedure: null,
1163+
graphQLOperationForStoredProcedure: null,
1164+
description: null,
1165+
parametersNameCollection: null,
1166+
parametersDescriptionCollection: null,
1167+
parametersRequiredCollection: null,
1168+
parametersDefaultCollection: null,
1169+
fieldsNameCollection: new[] { "Id" },
1170+
fieldsAliasCollection: null,
1171+
fieldsDescriptionCollection: new[] { "Unique Key" },
1172+
fieldsPrimaryKeyCollection: primaryKeyFlags,
1173+
mcpDmlTools: null,
1174+
mcpCustomTool: null
1175+
);
1176+
1177+
Assert.IsTrue(RuntimeConfigLoader.TryParseConfig(initialConfig, out RuntimeConfig? runtimeConfig), "Parsed config file.");
1178+
Assert.IsTrue(TryUpdateExistingEntity(options, runtimeConfig!, out RuntimeConfig updatedRuntimeConfig), "Successfully updated entity in the config.");
1179+
1180+
Entity updatedEntity = updatedRuntimeConfig.Entities["MyEntity"];
1181+
Assert.IsNotNull(updatedEntity.Fields);
1182+
Assert.AreEqual(1, updatedEntity.Fields!.Count);
1183+
FieldMetadata field = updatedEntity.Fields[0];
1184+
Assert.AreEqual("Id", field.Name);
1185+
Assert.AreEqual("Unique Key", field.Description);
1186+
Assert.AreEqual(expectedPrimaryKey, field.PrimaryKey);
1187+
}
1188+
11031189
private static string GetInitialConfigString()
11041190
{
11051191
return @"{" +

src/Cli/ConfigGenerator.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1747,6 +1747,7 @@ public static bool TryUpdateExistingEntity(UpdateOptions options, RuntimeConfig
17471747
List<FieldMetadata> updatedFieldsList = ComposeFieldsFromOptions(options);
17481748
Dictionary<string, FieldMetadata> updatedFieldsDict = updatedFieldsList.ToDictionary(f => f.Name, f => f);
17491749
List<FieldMetadata> mergedFields = [];
1750+
bool primaryKeyOptionProvided = options.FieldsPrimaryKeyCollection?.Any() == true;
17501751

17511752
foreach (FieldMetadata field in existingFields)
17521753
{
@@ -1757,7 +1758,10 @@ public static bool TryUpdateExistingEntity(UpdateOptions options, RuntimeConfig
17571758
Name = updatedField.Name,
17581759
Alias = updatedField.Alias ?? field.Alias,
17591760
Description = updatedField.Description ?? field.Description,
1760-
PrimaryKey = updatedField.PrimaryKey
1761+
// If --fields.primary-key was not provided at all,
1762+
// keep the existing primary-key flag. Otherwise,
1763+
// use the value coming from updatedField.
1764+
PrimaryKey = primaryKeyOptionProvided ? updatedField.PrimaryKey : field.PrimaryKey
17611765
});
17621766
updatedFieldsDict.Remove(field.Name); // Remove so only new fields remain
17631767
}

0 commit comments

Comments
 (0)