diff options
| author | Jake Mannens <jake@asger.xyz> | 2024-11-01 16:20:57 +1100 |
|---|---|---|
| committer | Jake Mannens <jake@asger.xyz> | 2024-11-06 12:03:04 +1100 |
| commit | 172b9e1a9156a79730eeef481f18290a7c920cbd (patch) | |
| tree | 8dccc1b7d6c4d87b5064a44a8de9f442dfbf2086 /BartService.cs | |
| parent | 2f4a6f26ad2581b974cddccc3f33d768bef441a9 (diff) | |
Framework for granular hourly record updates
Diffstat (limited to 'BartService.cs')
| -rw-r--r-- | BartService.cs | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/BartService.cs b/BartService.cs index 9966a7e..b7dffda 100644 --- a/BartService.cs +++ b/BartService.cs @@ -146,12 +146,23 @@ namespace PagerParser.Bart { return; } + // Fetch the most recent status for each member returned by BART + // across the requested time span. We'll use this to check if a + // member's status has changed since the last fetch, and if an + // entry reflecting the modified availability status needs to be + // recorded in the DB. + // + // The reason we do this, is to achieve a more granular availability + // history reflecting updates to each hour. BART's availability + // endpoint will only tell us when a member last updated the status + // for an entire day, so by comparing each hour to the last fetch, + // we can build a history of exactly which hourly slots have changed + // and when. var existingRecords = db.BartAvailabilityRecords .Include(r => r.Member) - .IntersectBy(users.Select(u => u.BartMemberId), r => r.Member.BartMemberId) - .OrderByDescending(r => r.Timestamp) - .GroupBy(r => r.Timestamp) - .Select(g => g.First()) + .Where(r => users.Select(u => u.BartMemberId).Contains(r.Member.BartMemberId)) + .GroupBy(r => new { r.Member.BartMemberId, r.Timestamp }) + .Select(g => g.OrderBy(r => r.Timestamp).Last()) .ToArray(); LinkedList<BartAvailabilityRecord> availabilityRecords = new(); @@ -178,6 +189,18 @@ namespace PagerParser.Bart { CreatedBy = users.FirstOrDefault(u => u.MemberName == entry.CreatedBy) }; + // If the availability for this hour is present in the + // database and hasn't changed since the last fetch, + // skip it + var exists = existingRecords + .Where(r => r.Member.BartMemberId == record.Member.BartMemberId) + .Where(r => r.Timestamp == record.Timestamp) + .Where(r => r.Status == record.Status) + .Any(); + + if(exists) + continue; + // Optionally set the create/modify time if // one is present in the fetched record if(entry.ModifiedOn is not null) @@ -195,11 +218,8 @@ namespace PagerParser.Bart { } } - var toAdd = availabilityRecords - .ExceptBy(db.BartAvailabilityRecords.Select(e => e.Hashcode), e => e.Hashcode); - try { - await db.BartAvailabilityRecords.AddRangeAsync(toAdd); + await db.BartAvailabilityRecords.AddRangeAsync(availabilityRecords); await db.SaveChangesAsync(); } catch(Exception e) { logger.LogError(e, "Error committing availability entries to the DB"); |
