// Map ODBC row to source member public static SrcMbr RowToSrcMbr(OdbcDataReader reader) { var mbr = new SrcMbr(); mbr.Name = reader.GetString(0).Trim(); // TABLE_PARTITION mbr.Attribute = reader.GetString(1).Trim(); // SOURCE_TYPE mbr.LineCount = reader.GetInt32(2); // NUMBER_ROWS mbr.Text = reader.GetString(3).Trim(); // PARTITION_TEXT mbr.RecordLength = reader.GetInt32(4); // AVGROWSIZE mbr.DataSize = reader.GetInt32(5); // DATA_SIZE mbr.Created = reader.GetDateTime(6); // CREATE_TIMESTAMP mbr.Updated = reader.GetDateTime(7); // LAST_CHANGE_TIMESTAMP return(mbr); }
// split src member from byte array to records, based on record length of source physical file private List <string> SplitSrcMbr(SrcMbr srcMbr) { List <string> src = new List <string>(); int rcdLen = srcMbr.RecordLength - 12; // Ex: RPG 92-12 = 80 columns byte[] record; for (int i = 0; i < srcMbr.Content.Length; i += rcdLen) { record = new byte[rcdLen]; Array.Copy(srcMbr.Content, i, record, 0, rcdLen); src.Add(Encoding.UTF8.GetString(record).TrimEnd()); } return(src); }
// Download source member at LIB/SRCPF/MBR public void GetMember(string qsysPath, string downloadPath) { if (!RegexUtils.MatchSrcMbrPath(qsysPath)) { throw new KanpachiFormatException("Expected source member path of format LIB/SRCPF/MBR."); } var splitPath = qsysPath.ToUpper().Split('/'); (string lib, string spf, string mbr) = (splitPath[0], splitPath[1], splitPath[2]); var srcPath = $"/QSYS.LIB/{lib}.LIB/{spf}.FILE/{mbr}.MBR"; var clientPath = BuildLocalQsysPath(downloadPath, lib, spf); using (KanpachiClient client = new KanpachiClient(Profile)){ SrcMbr srcMbr = client.GetSrcMbrDetails(lib, spf, mbr); DownloadSrcMbr(client, downloadPath, lib, spf, srcMbr); } }
// download source member and write to local file private void DownloadSrcMbr(KanpachiClient client, string downloadPath, string lib, string spf, SrcMbr srcMbr) { var outPath = Path.Combine(BuildLocalQsysPath(downloadPath, lib, spf), $"{srcMbr.Name}.{srcMbr.Attribute}"); var qsysPath = $"/QSYS.LIB/{lib}.LIB/{spf}.FILE/{srcMbr.Name}.MBR"; WriteQsysMetadata(client, downloadPath, lib, spf, srcMbr); Console.WriteLine($"Downloading {qsysPath} to {outPath}"); srcMbr.Content = client.DownloadMember(qsysPath); File.WriteAllText(outPath, string.Join("\n", SplitSrcMbr(srcMbr))); }
// write QSYS metadata (TEXT, RECORDLEN, ATTRIBUTE, etc) private void WriteQsysMetadata(KanpachiClient client, string downloadPath, string lib, string spf, SrcMbr mbr) { Library library = null; var metadataPath = Path.Combine(ClientUtils.BuildDownloadPath(downloadPath, Profile), "QSYS", lib, $"{lib}.json"); if (File.Exists(metadataPath)) { // read existing metadata file for update using (StreamReader f = File.OpenText(metadataPath)){ library = (Library) new JsonSerializer().Deserialize(f, typeof(Library)); int spfIdx = library.SrcPfs.FindIndex(x => x.Name == spf); // source physical file not found in library metadata, so add it if (spfIdx == -1) { library.SrcPfs.Add(client.GetSrcPfDetails(lib, spf)); spfIdx = library.SrcPfs.Count - 1; } SrcPf srcPf = library.SrcPfs[spfIdx]; int mbrIdx = srcPf.Members.FindIndex(x => x.Name == mbr.Name); // source member not found in source physical file metadata, so add it if (mbrIdx == -1) { srcPf.Members.Add(mbr); mbrIdx = srcPf.Members.Count - 1; } library.SrcPfs[spfIdx].Members[mbrIdx] = mbr; } } else { // library doesn't exist in metadata, setup new one library = client.GetLibraryDetails(lib); SrcPf srcPf = client.GetSrcPfDetails(lib, spf); srcPf.Members.Add(mbr); library.SrcPfs.Add(srcPf); } // update metadata file using (StreamWriter f = File.CreateText(metadataPath)){ f.Write(JsonConvert.SerializeObject(library, Formatting.Indented, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() })); } }