Private/ConvertTo-DhTreeTableJson.ps1
|
<# Tree-table JSON (v3.0.0). Add-DhTreeTable takes up to 100,000 rows and as many memberships; the generic per-row pipeline spent most of a large export in ForEach-Object and function-call overhead (about 17 s for 50,000 rows, now 4). Each row is checked once for characters the escaper would rewrite; a plain row is written with one interpolated string, anything else goes through ConvertTo-DhJsonString, so the output is byte-identical to the generic path. Properties are read through .PSBase: a property may be named Count or Keys. #> function ConvertTo-DhTreeTableRowsJson { <# The rows array body (no brackets): {"id","parent","type","label","status"[,"flags"][,"props"][,"detail"]}, ... #> param([object[]] $Rows) $esc = $script:DhJsonEscapeChars $parts = [System.Collections.Generic.List[string]]::new(@($Rows).Count) foreach ($tr in $Rows) { $id = [string]$tr.Id; $pa = [string]$tr.ParentId; $ty = [string]$tr.Type; $lb = [string]$tr.Label; $st = [string]$tr.Status $row = if (($id + $pa + $ty + $lb + $st).IndexOfAny($esc) -lt 0) { "{`"id`":`"$id`",`"parent`":`"$pa`",`"type`":`"$ty`",`"label`":`"$lb`",`"status`":`"$st`"" } else { '{"id":' + (ConvertTo-DhJsonString $id) + ',"parent":' + (ConvertTo-DhJsonString $pa) + ',"type":' + (ConvertTo-DhJsonString $ty) + ',"label":' + (ConvertTo-DhJsonString $lb) + ',"status":' + (ConvertTo-DhJsonString $st) } $fl = @($tr.Flags) if ($fl.Count) { $row += if (($fl -join "`u{1}").IndexOfAny($esc) -lt 0) { ',"flags":["' + ($fl -join '","') + '"]' } else { ',"flags":[' + ((@(foreach ($f in $fl) { ConvertTo-DhJsonString ([string]$f) })) -join ',') + ']' } } $pr = $tr.Properties if ($pr.PSBase.Count) { $pp = foreach ($k in $pr.PSBase.Keys) { $kl = [string]$k; $kv = [string]$pr[$k] if (($kl + $kv).IndexOfAny($esc) -lt 0) { "{`"label`":`"$kl`",`"value`":`"$kv`"}" } else { '{"label":' + (ConvertTo-DhJsonString $kl) + ',"value":' + (ConvertTo-DhJsonString $kv) + '}' } } $row += ',"props":[' + (@($pp) -join ',') + ']' } if ($tr.Detail) { $row += ',"detail":' + (ConvertTo-DhDetailJson $tr.Detail) } $parts.Add($row + '}') } return $parts -join ',' } function ConvertTo-DhTreeTableLinksJson { <# The memberships array body: ["groupId","memberId"], ... #> param([object[]] $Links) $esc = $script:DhJsonEscapeChars $parts = [System.Collections.Generic.List[string]]::new(@($Links).Count) foreach ($l in $Links) { $g = [string]$l.GroupId; $m = [string]$l.MemberId $parts.Add($(if (($g + $m).IndexOfAny($esc) -lt 0) { "[`"$g`",`"$m`"]" } else { '[' + (ConvertTo-DhJsonString $g) + ',' + (ConvertTo-DhJsonString $m) + ']' })) } return $parts -join ',' } |