public Task <PKSystem> UpdateSystem(IPKConnection conn, SystemId id, SystemPatch patch)
 {
     _logger.Information("Updated {SystemId}: {@SystemPatch}", id, patch);
     var(query, pms) = patch.Apply(UpdateQueryBuilder.Update("systems", "id = @id"))
                       .WithConstant("id", id)
                       .Build("returning *");
     return(conn.QueryFirstAsync <PKSystem>(query, pms));
 }
 public static SystemPatch WithAllPrivacy(this SystemPatch system, PrivacyLevel level)
 {
     foreach (var subject in Enum.GetValues(typeof(SystemPrivacySubject)))
     {
         WithPrivacy(system, (SystemPrivacySubject)subject, level);
     }
     return(system);
 }
        public static SystemPatch WithPrivacy(this SystemPatch system, SystemPrivacySubject subject, PrivacyLevel level)
        {
            // what do you mean switch expressions can't be statements >.>
            _ = subject switch
            {
                SystemPrivacySubject.Description => system.DescriptionPrivacy   = level,
                SystemPrivacySubject.Front => system.FrontPrivacy               = level,
                SystemPrivacySubject.FrontHistory => system.FrontHistoryPrivacy = level,
                SystemPrivacySubject.MemberList => system.MemberListPrivacy     = level,
                _ => throw new ArgumentOutOfRangeException($"Unknown privacy subject {subject}")
            };

            return(system);
        }
Example #4
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);
        }
Example #5
0
 public static Task <PKSystem> UpdateSystem(this IPKConnection conn, SystemId id, SystemPatch patch)
 {
     var(query, pms) = patch.Apply(UpdateQueryBuilder.Update("systems", "id = @id"))
                       .WithConstant("id", id)
                       .Build("returning *");
     return(conn.QueryFirstAsync <PKSystem>(query, pms));
 }