private async Task DoSwitchCommand(Context ctx, ICollection <PKMember> members) { // Make sure there are no dupes in the list // We do this by checking if removing duplicate member IDs results in a list of different length if (members.Select(m => m.Id).Distinct().Count() != members.Count) { throw Errors.DuplicateSwitchMembers; } // Find the last switch and its members if applicable await using var conn = await _db.Obtain(); var lastSwitch = await _repo.GetLatestSwitch(conn, ctx.System.Id); if (lastSwitch != null) { var lastSwitchMembers = _repo.GetSwitchMembers(conn, lastSwitch.Id); // Make sure the requested switch isn't identical to the last one if (await lastSwitchMembers.Select(m => m.Id).SequenceEqualAsync(members.Select(m => m.Id).ToAsyncEnumerable())) { throw Errors.SameSwitch(members, ctx.LookupContextFor(ctx.System)); } } await _repo.AddSwitch(conn, ctx.System.Id, members.Select(m => m.Id).ToList()); if (members.Count == 0) { await ctx.Reply($"{Emojis.Success} Switch-out registered."); } else { await ctx.Reply($"{Emojis.Success} Switch registered. Current fronter is now {string.Join(", ", members.Select(m => m.NameFor(ctx)))}."); } }
public async Task <IActionResult> PostSwitch([FromBody] PostSwitchParams param) { if (param.Members.Distinct().Count() != param.Members.Count) { return(BadRequest("Duplicate members in member list.")); } await using var conn = await _db.Obtain(); // We get the current switch, if it exists var latestSwitch = await _repo.GetLatestSwitch(User.CurrentSystem()); if (latestSwitch != null) { var latestSwitchMembers = _repo.GetSwitchMembers(conn, latestSwitch.Id); // Bail if this switch is identical to the latest one if (await latestSwitchMembers.Select(m => m.Hid).SequenceEqualAsync(param.Members.ToAsyncEnumerable())) { return(BadRequest("New members identical to existing fronters.")); } } // Resolve member objects for all given IDs var membersList = (await conn.QueryAsync <PKMember>("select * from members where hid = any(@Hids)", new { Hids = param.Members })).ToList(); foreach (var member in membersList) { if (member.System != User.CurrentSystem()) { return(BadRequest($"Cannot switch to member '{member.Hid}' not in system.")); } } // membersList is in DB order, and we want it in actual input order // so we go through a dict and map the original input appropriately var membersDict = membersList.ToDictionary(m => m.Hid); var membersInOrder = new List <PKMember>(); // We do this without .Select() since we want to have the early return bail if it doesn't find the member foreach (var givenMemberId in param.Members) { if (!membersDict.TryGetValue(givenMemberId, out var member)) { return(BadRequest($"Member '{givenMemberId}' not found.")); } membersInOrder.Add(member); } // Finally, log the switch (yay!) await _repo.AddSwitch(conn, User.CurrentSystem(), membersInOrder.Select(m => m.Id).ToList()); return(NoContent()); }