public static async Task <BulkImporter> Begin(PKSystem system, IPKConnection conn) { var tx = await conn.BeginTransactionAsync(); var importer = new BulkImporter(system.Id, conn, tx); await importer.Begin(); return(importer); }
public async Task <ImportResult> ImportSystem(DataFileSystem data, PKSystem system, ulong accountId) { var result = new ImportResult { AddedNames = new List <string>(), ModifiedNames = new List <string>(), System = system, Success = true // Assume success unless indicated otherwise }; // If we don't already have a system to save to, create one if (system == null) { system = result.System = await _data.CreateSystem(data.Name); await _data.AddAccount(system, accountId); } await using var conn = await _db.Obtain(); // Apply system info var patch = new SystemPatch { Name = data.Name }; if (data.Description != null) { patch.Description = data.Description; } if (data.Tag != null) { patch.Tag = data.Tag; } if (data.AvatarUrl != null) { patch.AvatarUrl = data.AvatarUrl; } if (data.TimeZone != null) { patch.UiTz = data.TimeZone ?? "UTC"; } await conn.UpdateSystem(system.Id, patch); // -- Member/switch import -- await using (var imp = await BulkImporter.Begin(system, conn)) { // Tally up the members that didn't exist before, and check member count on import // If creating the unmatched members would put us over the member limit, abort before creating any members var memberCountBefore = await conn.GetSystemMemberCount(system.Id); var membersToAdd = data.Members.Count(m => imp.IsNewMember(m.Id, m.Name)); if (memberCountBefore + membersToAdd > Limits.MaxMemberCount) { result.Success = false; result.Message = $"Import would exceed the maximum number of members ({Limits.MaxMemberCount})."; return(result); } async Task DoImportMember(BulkImporter imp, DataFileMember fileMember) { var isCreatingNewMember = imp.IsNewMember(fileMember.Id, fileMember.Name); // Use the file member's id as the "unique identifier" for the importing (actual value is irrelevant but needs to be consistent) _logger.Debug( "Importing member with identifier {FileId} to system {System} (is creating new member? {IsCreatingNewMember})", fileMember.Id, system.Id, isCreatingNewMember); var newMember = await imp.AddMember(fileMember.Id, fileMember.Id, fileMember.Name, ToMemberPatch(fileMember)); if (isCreatingNewMember) { result.AddedNames.Add(newMember.Name); } else { result.ModifiedNames.Add(newMember.Name); } } // Can't parallelize this because we can't reuse the same connection/tx inside the importer foreach (var m in data.Members) { await DoImportMember(imp, m); } // Lastly, import the switches await imp.AddSwitches(data.Switches.Select(sw => new BulkImporter.SwitchInfo { Timestamp = DateTimeFormats.TimestampExportFormat.Parse(sw.Timestamp).Value, // "Members" here is from whatever ID the data file uses, which the bulk importer can map to the real IDs! :) MemberIdentifiers = sw.Members.ToList() }).ToList()); } _logger.Information("Imported system {System}", system.Hid); return(result); }