Skip to content

Commit

Permalink
Merge pull request #602 from osu-tournament-rating/feature/ef-naming-…
Browse files Browse the repository at this point in the history
…conventions

Snake case by default database refactor
  • Loading branch information
hburn7 authored Feb 19, 2025
2 parents 525356a + 368d7fd commit 666925a
Show file tree
Hide file tree
Showing 56 changed files with 1,032 additions and 931 deletions.
2 changes: 1 addition & 1 deletion API/Configurations/MapperProfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public MapperProfile()
CreateMap<AdminNoteEntityBase, AdminNoteDTO>();

CreateMap<Beatmap, BeatmapDTO>();
CreateMap<BeatmapSet, BeatmapSetCompactDTO>();
CreateMap<Beatmapset, BeatmapsetCompactDTO>();
CreateMap<BeatmapAttributes, BeatmapAttributesDTO>();

CreateMap<Game, GameDTO>()
Expand Down
4 changes: 2 additions & 2 deletions API/DTOs/BeatmapDTO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ public class BeatmapDTO
/// <summary>
/// Beatmapset id
/// </summary>
public int? BeatmapSetId { get; set; }
public int? BeatmapsetId { get; set; }

/// <summary>
/// Beatmapset
/// </summary>
public BeatmapSetCompactDTO? BeatmapSet { get; init; }
public BeatmapsetCompactDTO? Beatmapset { get; init; }

Check notice on line 66 in API/DTOs/BeatmapDTO.cs

View workflow job for this annotation

GitHub Actions / Qodana for .NET

Type member is never used (non-private accessibility)

Property 'Beatmapset' is never used

/// <summary>
/// Beatmap attributes
Expand Down
2 changes: 1 addition & 1 deletion API/DTOs/BeatmapSetCompactDTO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace API.DTOs;
/// <summary>
/// Represents a compact version of a beatmapset
/// </summary>
public class BeatmapSetCompactDTO
public class BeatmapsetCompactDTO
{
/// <summary>
/// Beatmapset id
Expand Down
2 changes: 1 addition & 1 deletion API/DTOs/BeatmapSetDTO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ namespace API.DTOs;
/// <summary>
/// A beatmapset with beatmaps included
/// </summary>
public class BeatmapSetDTO : BeatmapSetCompactDTO
public class BeatmapsetDTO : BeatmapsetCompactDTO
{
/// <summary>
/// Beatmaps which are part of this set
Expand Down
3 changes: 2 additions & 1 deletion API/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,8 @@ await context.HttpContext.Response.WriteAsync(
{
options
.UseNpgsql(builder.Configuration.BindAndValidate<ConnectionStringsConfiguration>(ConnectionStringsConfiguration.Position).DefaultConnection)
.AddInterceptors(services.GetRequiredService<AuditBlamingInterceptor>());
.AddInterceptors(services.GetRequiredService<AuditBlamingInterceptor>())
.UseSnakeCaseNamingConvention();
});

// The Redis cache is registered as a singleton because it is meant to be re-used across instances
Expand Down
2 changes: 1 addition & 1 deletion API/Services/Implementations/PlayerStatsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ await matchStatsRepository.OpponentStatsAsync(playerId, opponentId, ruleset, dat
return null;
}

ruleset ??= player.User?.Settings.DefaultRuleset ?? player.Ruleset;
ruleset ??= player.User?.Settings.DefaultRuleset ?? player.DefaultRuleset;

PlayerCompactDTO playerInfo = mapper.Map<PlayerCompactDTO>(player);

Expand Down
2 changes: 1 addition & 1 deletion API/Services/Implementations/SearchService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ private async Task<IEnumerable<PlayerSearchResultDTO>> SearchPlayersByNameAsync(
.Select(player =>
{
PlayerRating? stats = player.Ratings
.FirstOrDefault(r => r.Ruleset == (player.User?.Settings.DefaultRuleset ?? player.Ruleset));
.FirstOrDefault(r => r.Ruleset == (player.User?.Settings.DefaultRuleset ?? player.DefaultRuleset));
return new PlayerSearchResultDTO
{
Id = player.Id,
Expand Down
2 changes: 1 addition & 1 deletion API/Services/Implementations/UserSettingsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public async Task<bool> SyncRulesetAsync(int userId)
return false;
}

user.Settings.DefaultRuleset = user.Player!.Ruleset;
user.Settings.DefaultRuleset = user.Player!.DefaultRuleset;

Check warning on line 35 in API/Services/Implementations/UserSettingsService.cs

View workflow job for this annotation

GitHub Actions / Qodana for .NET

Redundant nullable warning suppression expression

The nullable warning suppression expression is redundant
user.Settings.DefaultRulesetIsControlled = false;
await userRepository.UpdateAsync(user);

Expand Down
3 changes: 2 additions & 1 deletion DataWorkerService/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@
)
.DefaultConnection
)
.AddInterceptors(new AuditingInterceptor());
.AddInterceptors(new AuditingInterceptor())
.UseSnakeCaseNamingConvention();
});

AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using ApiScore = OsuApiClient.Domain.Osu.Multiplayer.GameScore;
using ApiUser = OsuApiClient.Domain.Osu.Users.User;
using Beatmap = Database.Entities.Beatmap;
using Beatmapset = Database.Entities.Beatmapset;
using GameScore = Database.Entities.GameScore;

namespace DataWorkerService.Services.Implementations;
Expand All @@ -20,7 +21,7 @@ public class OsuApiDataParserService(
IOsuClient osuClient
) : IOsuApiDataParserService
{
private readonly Dictionary<long, BeatmapSet> _beatmapSetCache = [];
private readonly Dictionary<long, Beatmapset> _beatmapSetCache = [];
private readonly Dictionary<long, Beatmap> _beatmapCache = [];
private readonly Dictionary<long, Player> _playerCache = [];

Expand Down Expand Up @@ -143,7 +144,7 @@ public async Task ProcessBeatmapsAsync(IEnumerable<long> beatmapOsuIds)

// Test database
Beatmap? beatmap = await context.Beatmaps
.Include(b => b.BeatmapSet)
.Include(b => b.Beatmapset)
.ThenInclude(bs => bs!.Creator)
.Include(b => b.Creators)
.FirstOrDefaultAsync(b => b.OsuId == beatmapOsuId);
Expand All @@ -153,12 +154,12 @@ public async Task ProcessBeatmapsAsync(IEnumerable<long> beatmapOsuIds)
{
_beatmapCache.TryAdd(beatmap.OsuId, beatmap);
beatmap.Creators.ToList().ForEach(p => _playerCache.TryAdd(p.OsuId, p));
if (beatmap.BeatmapSet is not null)
if (beatmap.Beatmapset is not null)
{
_beatmapSetCache.TryAdd(beatmap.BeatmapSet.OsuId, beatmap.BeatmapSet);
if (beatmap.BeatmapSet.Creator is not null)
_beatmapSetCache.TryAdd(beatmap.Beatmapset.OsuId, beatmap.Beatmapset);
if (beatmap.Beatmapset.Creator is not null)
{
_playerCache.TryAdd(beatmap.BeatmapSet.Creator.OsuId, beatmap.BeatmapSet.Creator);
_playerCache.TryAdd(beatmap.Beatmapset.Creator.OsuId, beatmap.Beatmapset.Creator);
}
}
}
Expand All @@ -170,7 +171,7 @@ public async Task ProcessBeatmapsAsync(IEnumerable<long> beatmapOsuIds)
_beatmapCache.TryAdd(beatmap.OsuId, beatmap);
}

if (beatmap.BeatmapSet is not null || beatmap.HasData)
if (beatmap.Beatmapset is not null || beatmap.HasData)
{
continue;
}
Expand All @@ -183,11 +184,11 @@ public async Task ProcessBeatmapsAsync(IEnumerable<long> beatmapOsuIds)
continue;
}

await ProcessBeatmapSetAsync(apiBeatmap.BeatmapsetId);
await ProcessBeatmapsetAsync(apiBeatmap.BeatmapsetId);
}
}

private async Task ProcessBeatmapSetAsync(long beatmapSetOsuId)
private async Task ProcessBeatmapsetAsync(long beatmapSetOsuId)
{
// Test cache
if (_beatmapSetCache.ContainsKey(beatmapSetOsuId))
Expand All @@ -196,7 +197,7 @@ private async Task ProcessBeatmapSetAsync(long beatmapSetOsuId)
}

// Test database
BeatmapSet? beatmapSet = await context.BeatmapSets
Beatmapset? beatmapSet = await context.Beatmapsets
.AsSplitQuery()
.Include(bs => bs.Creator)
.Include(bs => bs.Beatmaps)
Expand All @@ -221,14 +222,14 @@ private async Task ProcessBeatmapSetAsync(long beatmapSetOsuId)
return;
}

BeatmapsetExtended? apiBeatmapSet = await osuClient.GetBeatmapsetAsync(beatmapSetOsuId);
BeatmapsetExtended? apiBeatmapset = await osuClient.GetBeatmapsetAsync(beatmapSetOsuId);

// Could not fetch the set, create an empty entity
if (apiBeatmapSet is null)
if (apiBeatmapset is null)
{
beatmapSet = new BeatmapSet { OsuId = beatmapSetOsuId };
beatmapSet = new Beatmapset { OsuId = beatmapSetOsuId };

context.BeatmapSets.Add(beatmapSet);
context.Beatmapsets.Add(beatmapSet);
_beatmapSetCache.TryAdd(beatmapSet.OsuId, beatmapSet);

return;
Expand All @@ -237,31 +238,31 @@ private async Task ProcessBeatmapSetAsync(long beatmapSetOsuId)
// Now we parse
// Load players
// Filtering because this collection also contains beatmap nominators, etc. and we only want to target mappers
await LoadPlayersAsync(apiBeatmapSet.RelatedUsers.Where(u =>
u.Id == apiBeatmapSet.CreatorId || apiBeatmapSet.Beatmaps
await LoadPlayersAsync(apiBeatmapset.RelatedUsers.Where(u =>
u.Id == apiBeatmapset.CreatorId || apiBeatmapset.Beatmaps
.SelectMany(b => b.Owners)
.Any(o => o.Id == u.Id))
);

// Create new set
beatmapSet = new BeatmapSet
beatmapSet = new Beatmapset
{
OsuId = beatmapSetOsuId,
Artist = apiBeatmapSet.Artist,
Title = apiBeatmapSet.Title,
RankedStatus = apiBeatmapSet.RankedStatus,
RankedDate = apiBeatmapSet.RankedDate,
SubmittedDate = apiBeatmapSet.SubmittedDate,
Artist = apiBeatmapset.Artist,
Title = apiBeatmapset.Title,
RankedStatus = apiBeatmapset.RankedStatus,
RankedDate = apiBeatmapset.RankedDate,
SubmittedDate = apiBeatmapset.SubmittedDate,

Check notice on line 255 in DataWorkerService/Services/Implementations/OsuApiDataParserService.cs

View workflow job for this annotation

GitHub Actions / Qodana for .NET

Use preferred style for trailing comma before new line in multiline lists

Remove trailing comma to conform to code style
};

// Assign set creator if possible
if (apiBeatmapSet.CreatorId is not null && _playerCache.TryGetValue(apiBeatmapSet.CreatorId.Value, out Player? setCreator))
if (apiBeatmapset.CreatorId is not null && _playerCache.TryGetValue(apiBeatmapset.CreatorId.Value, out Player? setCreator))
{
beatmapSet.Creator = setCreator;
}

// Parse maps
foreach (BeatmapExtended apiBeatmap in apiBeatmapSet.Beatmaps)
foreach (BeatmapExtended apiBeatmap in apiBeatmapset.Beatmaps)
{
// Test cache
_beatmapCache.TryGetValue(apiBeatmap.Id, out Beatmap? beatmap);
Expand Down Expand Up @@ -304,7 +305,7 @@ await LoadPlayersAsync(apiBeatmapSet.RelatedUsers.Where(u =>
}

_beatmapSetCache.TryAdd(beatmapSet.OsuId, beatmapSet);
context.BeatmapSets.Add(beatmapSet);
context.Beatmapsets.Add(beatmapSet);
}

private async Task LoadPlayersAsync(IEnumerable<ApiUser> apiUsers)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public async Task UpdateFromOsuApiAsync(Player player)
{
player.Username = result.Username;
player.Country = result.CountryCode;
player.Ruleset = result.Ruleset;
player.DefaultRuleset = result.Ruleset;

if (player.User?.Settings is { DefaultRulesetIsControlled: false })
{
Expand Down
1 change: 1 addition & 0 deletions Database/Database.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="EFCore.NamingConventions" Version="9.0.0" />
<PackageReference Include="JetBrains.Annotations" Version="2024.3.0"/>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.0"/>
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="9.0.0"/>
Expand Down
3 changes: 0 additions & 3 deletions Database/Entities/AdminNoteEntityBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,10 @@ namespace Database.Entities;
/// </summary>
public abstract class AdminNoteEntityBase : UpdateableEntityBase, IAdminNoteEntity
{
[Column("note")]
public string Note { get; set; } = string.Empty;

[Column("ref_id")]
public int ReferenceId { get; set; }

[Column("admin_user_id")]
public int AdminUserId { get; set; }

public User AdminUser { get; } = null!;

Check notice on line 17 in Database/Entities/AdminNoteEntityBase.cs

View workflow job for this annotation

GitHub Actions / Qodana for .NET

Replace auto-property with computed property

Replace auto-property with computed property
Expand Down
7 changes: 0 additions & 7 deletions Database/Entities/AuditEntityBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,19 @@ public abstract class AuditEntityBase<TAuditable, TAudit> : IAuditEntity
where TAudit : IAuditEntity
{
[Key]
[Column("id")]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; }

[Column("created")]
public DateTime Created { get; }

[Column("ref_id_lock")]
public int ReferenceIdLock { get; private set; }

[Column("ref_id")]
public int? ReferenceId { get; private set; }

[Column("action_user_id")]
public int? ActionUserId { get; set; }

[Column("action_type")]
public AuditActionType ActionType { get; private set; }

[Column("changes", TypeName = "jsonb")]
public IDictionary<string, AuditChangelogEntry> Changes { get; } = new Dictionary<string, AuditChangelogEntry>();

public virtual bool GenerateAudit(EntityEntry origEntityEntry)
Expand Down
Loading

0 comments on commit 666925a

Please sign in to comment.