Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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);
        }