private static void ReadJsonDiffRow(JObject node, PersistonDiff.DiffRow target, TableDef tableDef, bool allowChildren) { //copy fields in this row foreach (var colDef in tableDef.Cols) { //get json value or skip var jtoken = node.GetValue(colDef.Name, StringComparison.OrdinalIgnoreCase); if (jtoken == null) { continue; } //copy var value = ParseNode(jtoken, colDef.CSType); target.Columns[colDef.Name] = value; } //recursively copy child rows if (tableDef.Children != null && allowChildren) { foreach (var childTableDef in tableDef.Children) { if (target.ChildTables == null) { target.ChildTables = new Dictionary <TableDef, List <PersistonDiff.DiffRow> >(); } if (!target.ChildTables.ContainsKey(childTableDef)) { target.ChildTables[childTableDef] = new List <PersistonDiff.DiffRow>(); } ReadJsonDiffRowArray(node, childTableDef, target.ChildTables[childTableDef]); } } }
/// <summary> /// Look for array nodes matching tableDef, such as Customer, Customer-new, Customer-deleted; and then /// construct target rows based on the values found in those arrays /// </summary> private static void ReadJsonDiffRowArray(JObject parent, TableDef tableDef, List <PersistonDiff.DiffRow> targetA) { void ParseArray(string arrayName, DiffKind kind, bool allowChildren, bool fillInMissingNegativeKey) { var rows = parent[arrayName]; if (rows == null) { return; } if (!(rows is JArray rowsA)) { throw new Exception($"Diff json nodes must be arrays"); } foreach (var childNode in rowsA) { if (!(childNode is JObject childObject)) { throw new Exception("Diff array members must be row objects, not values or arrays"); } var target = new PersistonDiff.DiffRow() { Kind = kind }; targetA.Add(target); ReadJsonDiffRow(childObject, target, tableDef, allowChildren); //if the client omits -1 primary key value on new rows, add it here; the save logic needs it but it is redundant from the client perspective if (fillInMissingNegativeKey && !target.Columns.ContainsKey(tableDef.PrimaryKeyColName)) { var newRowPK = Utils.ChangeType(-1, tableDef.FindCol(tableDef.PrimaryKeyColName).CSType); target.Columns[tableDef.PrimaryKeyColName] = newRowPK; } } } string name = CamelCasify(tableDef.Name); ParseArray(name, DiffKind.Other, true, false); ParseArray(name + "-new", DiffKind.NewRow, true, true); ParseArray(name + "-deleted", DiffKind.DeletedRow, false, false); }