Major database refactor (again)

This commit is contained in:
Ske
2020-08-29 13:46:27 +02:00
parent 3996cd48c7
commit c7612df37e
55 changed files with 1014 additions and 1100 deletions

View File

@@ -39,29 +39,29 @@ namespace PluralKit.API
[Route( "v{version:apiVersion}/s" )]
public class SystemController : ControllerBase
{
private IDataStore _data;
private IDatabase _db;
private IAuthorizationService _auth;
private readonly IDatabase _db;
private readonly ModelRepository _repo;
private readonly IAuthorizationService _auth;
public SystemController(IDataStore data, IDatabase db, IAuthorizationService auth)
public SystemController(IDatabase db, IAuthorizationService auth, ModelRepository repo)
{
_data = data;
_db = db;
_auth = auth;
_repo = repo;
}
[HttpGet]
[Authorize]
public async Task<ActionResult<JObject>> GetOwnSystem()
{
var system = await _db.Execute(c => c.QuerySystem(User.CurrentSystem()));
var system = await _db.Execute(c => _repo.GetSystem(c, User.CurrentSystem()));
return system.ToJson(User.ContextFor(system));
}
[HttpGet("{hid}")]
public async Task<ActionResult<JObject>> GetSystem(string hid)
{
var system = await _data.GetSystemByHid(hid);
var system = await _db.Execute(c => _repo.GetSystemByHid(c, hid));
if (system == null) return NotFound("System not found.");
return Ok(system.ToJson(User.ContextFor(system)));
}
@@ -69,13 +69,14 @@ namespace PluralKit.API
[HttpGet("{hid}/members")]
public async Task<ActionResult<IEnumerable<JObject>>> GetMembers(string hid)
{
var system = await _data.GetSystemByHid(hid);
if (system == null) return NotFound("System not found.");
var system = await _db.Execute(c => _repo.GetSystemByHid(c, hid));
if (system == null)
return NotFound("System not found.");
if (!system.MemberListPrivacy.CanAccess(User.ContextFor(system)))
return StatusCode(StatusCodes.Status403Forbidden, "Unauthorized to view member list.");
var members = _data.GetSystemMembers(system);
var members = _db.Execute(c => _repo.GetSystemMembers(c, system.Id));
return Ok(await members
.Where(m => m.MemberVisibility.CanAccess(User.ContextFor(system)))
.Select(m => m.ToJson(User.ContextFor(system)))
@@ -87,39 +88,40 @@ namespace PluralKit.API
{
if (before == null) before = SystemClock.Instance.GetCurrentInstant();
var system = await _data.GetSystemByHid(hid);
await using var conn = await _db.Obtain();
var system = await _repo.GetSystemByHid(conn, hid);
if (system == null) return NotFound("System not found.");
var auth = await _auth.AuthorizeAsync(User, system, "ViewFrontHistory");
if (!auth.Succeeded) return StatusCode(StatusCodes.Status403Forbidden, "Unauthorized to view front history.");
using (var conn = await _db.Obtain())
{
var res = await conn.QueryAsync<SwitchesReturn>(
@"select *, array(
var res = await conn.QueryAsync<SwitchesReturn>(
@"select *, array(
select members.hid from switch_members, members
where switch_members.switch = switches.id and members.id = switch_members.member
) as members from switches
where switches.system = @System and switches.timestamp < @Before
order by switches.timestamp desc
limit 100;", new {System = system.Id, Before = before});
return Ok(res);
}
return Ok(res);
}
[HttpGet("{hid}/fronters")]
public async Task<ActionResult<FrontersReturn>> GetFronters(string hid)
{
var system = await _data.GetSystemByHid(hid);
await using var conn = await _db.Obtain();
var system = await _repo.GetSystemByHid(conn, hid);
if (system == null) return NotFound("System not found.");
var auth = await _auth.AuthorizeAsync(User, system, "ViewFront");
if (!auth.Succeeded) return StatusCode(StatusCodes.Status403Forbidden, "Unauthorized to view fronter.");
var sw = await _data.GetLatestSwitch(system.Id);
var sw = await _repo.GetLatestSwitch(conn, system.Id);
if (sw == null) return NotFound("System has no registered switches.");
var members = _data.GetSwitchMembers(sw);
var members = _repo.GetSwitchMembers(conn, sw.Id);
return Ok(new FrontersReturn
{
Timestamp = sw.Timestamp,
@@ -131,7 +133,8 @@ namespace PluralKit.API
[Authorize]
public async Task<ActionResult<JObject>> EditSystem([FromBody] JObject changes)
{
var system = await _db.Execute(c => c.QuerySystem(User.CurrentSystem()));
await using var conn = await _db.Obtain();
var system = await _repo.GetSystem(conn, User.CurrentSystem());
SystemPatch patch;
try
@@ -143,7 +146,7 @@ namespace PluralKit.API
return BadRequest(e.Message);
}
await _db.Execute(conn => conn.UpdateSystem(system.Id, patch));
await _repo.UpdateSystem(conn, system!.Id, patch);
return Ok(system.ToJson(User.ContextFor(system)));
}
@@ -154,11 +157,13 @@ namespace PluralKit.API
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 _data.GetLatestSwitch(User.CurrentSystem());
var latestSwitch = await _repo.GetLatestSwitch(conn, User.CurrentSystem());
if (latestSwitch != null)
{
var latestSwitchMembers = _data.GetSwitchMembers(latestSwitch);
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()))
@@ -166,9 +171,7 @@ namespace PluralKit.API
}
// Resolve member objects for all given IDs
IEnumerable<PKMember> membersList;
using (var conn = await _db.Obtain())
membersList = (await conn.QueryAsync<PKMember>("select * from members where hid = any(@Hids)", new {Hids = param.Members})).ToList();
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())
@@ -182,12 +185,13 @@ namespace PluralKit.API
// 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.");
if (!membersDict.TryGetValue(givenMemberId, out var member))
return BadRequest($"Member '{givenMemberId}' not found.");
membersInOrder.Add(member);
}
// Finally, log the switch (yay!)
await _data.AddSwitch(User.CurrentSystem(), membersInOrder);
await _repo.AddSwitch(conn, User.CurrentSystem(), membersInOrder.Select(m => m.Id).ToList());
return NoContent();
}
}