using System.Collections.ObjectModel; using System.Text.Json; using Microsoft.Extensions.Logging; namespace File_Folder_Helper.ADO2025.PI5; internal static partial class Helper20250228 { private record Record(string TableName, ReadOnlyCollection Columns, ReadOnlyCollection Rows); internal static void PostgresDumpToJson(ILogger logger, List args) { string searchPattern = args[2]; string headerA = args[3].Replace('_', ' '); string headerB = args[4].Replace('_', ' '); string sourceDirectory = Path.GetFullPath(args[0]); string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories); if (files.Length != 1) logger.LogWarning("<{files}>(s)", files.Length); else PostgresDumpToJson(logger, headerA, headerB, files[0]); } private static void PostgresDumpToJson(ILogger logger, string headerA, string headerB, string file) { ReadOnlyCollection records = GetRecords(headerA, headerB, file); if (records.Count > 0) WriteFile(file, records); else logger.LogWarning("<{records}>(s)", records.Count); } private static ReadOnlyCollection GetRecords(string headerA, string headerB, string file) { List results = []; string line; string[] segmentsA; string[] segmentsB; string[] segmentsC; string[] segmentsD; string[] segmentsE; string[] segmentsF; List rows; string? tableName = null; string[] lines = File.ReadAllLines(file); ReadOnlyCollection? columns = null; for (int i = 0; i < lines.Length; i++) { line = lines[i]; if (tableName is null) { segmentsA = line.Split(headerA); if (segmentsA.Length != 2) continue; segmentsB = segmentsA[1].Split(headerB); if (segmentsB.Length != 2) continue; segmentsC = segmentsB[0].Split('('); if (segmentsC.Length != 2) continue; segmentsD = segmentsC[1].Split(')'); if (segmentsD.Length != 2) continue; columns = segmentsD[0].Split(',').Select(l => l.Trim(' ').Trim('"')).ToArray().AsReadOnly(); if (columns.Count == 0) continue; segmentsE = segmentsB[0].Split(' '); tableName = segmentsE[0]; } else if (columns is null) break; else { rows = []; for (int j = i + 1; j < lines.Length; j++) { i = j; segmentsF = lines[j].Split('\t'); if (segmentsF.Length != columns.Count) { if (rows.Count > 0) results.Add(new(TableName: tableName, Columns: columns, Rows: rows.AsReadOnly())); break; } rows.Add(segmentsF); } columns = null; tableName = null; } } return results.AsReadOnly(); } private static void WriteFile(string file, ReadOnlyCollection records) { List results = []; string json; string text; Dictionary keyValuePairs = []; foreach (Record record in records) { results.Clear(); foreach (string[] row in record.Rows) { keyValuePairs.Clear(); for (int i = 0; i < row.Length; i++) { if (row[i] == "\\N") keyValuePairs.Add(record.Columns[i], null); else keyValuePairs.Add(record.Columns[i], row[i]); } #pragma warning disable IL3050, IL2026 json = JsonSerializer.Serialize(keyValuePairs); #pragma warning restore IL3050, IL2026 results.Add(json); } text = string.Join($",{Environment.NewLine}", results); File.WriteAllText($"{file[..^4]}-{record.TableName}.json", $"[{Environment.NewLine}{text}{Environment.NewLine}]"); } } }