Skip to content

Commit

Permalink
Work on the api a bit more, rename migrations to what they are suppos…
Browse files Browse the repository at this point in the history
…ed to be for each db.
  • Loading branch information
sylveonnotdeko committed Apr 22, 2024
1 parent 3c6068b commit 16dd856
Show file tree
Hide file tree
Showing 11 changed files with 204 additions and 78 deletions.
34 changes: 22 additions & 12 deletions Mewdeko.Api/Controllers/GuildConfig.cs
Original file line number Diff line number Diff line change
@@ -1,31 +1,41 @@
using Mewdeko.Database;
using Mewdeko.Database.Extensions;
using Mewdeko.Api.Services;
using Mewdeko.Database.Models;
using Microsoft.AspNetCore.Mvc;
using Serilog;

namespace Mewdeko.Api.Controllers;

[ApiController]
[Route("api/[controller]")]
public class GuildConfig(DbService service) : Controller
[Route("api/[controller]/{guildId}")]
public class GuildConfigController(GuildSettingsService service) : Controller
{
[HttpGet("{guildId}")]
[HttpGet]
public async Task<IActionResult> GetGuildConfig(ulong guildId)
{
try
{
await using var uow = service.GetDbContext();
var guildConfig = await uow.ForGuildId(guildId);

if (guildConfig == null)
return NotFound();

return Ok(guildConfig);
var config = await service.GetGuildConfig(guildId);
return Ok(config);
}
catch (Exception e)
{
Log.Error(e, "Error getting guild config");
return StatusCode(500);
}
}

[HttpPost]
public async Task<IActionResult> UpdateGuildConfig(ulong guildId, [FromBody] GuildConfig model)
{
try
{
await service.UpdateGuildConfig(guildId, model);
return Ok();
}
catch (Exception e)
{
Log.Error(e, "Error updating guild config");
return StatusCode(500);
}
}
}
50 changes: 50 additions & 0 deletions Mewdeko.Api/Controllers/SuggestionsController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using LinqToDB;
using LinqToDB.EntityFrameworkCore;
using Mewdeko.Database;
using Microsoft.AspNetCore.Mvc;

namespace Mewdeko.Api.Controllers;

[ApiController]
[Route("api/[controller]")]
public class SuggestionsController(DbService dbService) : Controller
{
[HttpGet("{guildId}/{userId?}")]
public async Task<IActionResult> GetSuggestions(ulong guildId, ulong userId = 0)
{
await using var uow = dbService.GetDbContext();
var suggestions = await uow.Suggestions.ToLinqToDB().ToListAsync();
if (suggestions.Count == 0)
return NotFound("No suggestions in database at all.");

var guildSuggestions = suggestions.Where(x => x.GuildId == guildId);

if (!guildSuggestions.Any())
return NotFound("No suggestions for this guild.");

if (userId != 0)
{
var userSuggestions = guildSuggestions.Where(x => x.UserId == userId);
if (!userSuggestions.Any())
return NotFound("No suggestions for this user.");
return Ok(userSuggestions);
}

return Ok(guildSuggestions);
}

[HttpDelete("{id}")]
public async Task<IActionResult> DeleteSuggestion(int id)
{
await using var uow = dbService.GetDbContext();
var suggestion = await uow.Suggestions.FirstOrDefaultAsync(x => x.Id == id);

if (suggestion == null)
return NotFound();

uow.Suggestions.Remove(suggestion);
await uow.SaveChangesAsync();

return Ok();
}
}
1 change: 1 addition & 0 deletions Mewdeko.Api/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
var redis = new RedisCache(redisUrl, redisKey);

builder.Services.AddSingleton(redis);
builder.Services.AddSingleton(new GuildSettingsService(db, redis));

var app = builder.Build();

Expand Down
85 changes: 85 additions & 0 deletions Mewdeko.Api/Services/GuildSettingsService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using Mewdeko.Database;
using Mewdeko.Database.Extensions;
using Mewdeko.Database.Models;

namespace Mewdeko.Api.Services;

/// <summary>
/// Service for managing guild settings.
/// </summary>
public class GuildSettingsService(
DbService db,
RedisCache cache)
{
/// <summary>
/// Gets the guild configuration for the specified guild ID.
/// </summary>
public async Task<GuildConfig> GetGuildConfig(ulong guildId)
{
var configExists = await cache.GetGuildConfigCache(guildId);
if (configExists != null)
return configExists;

await using var uow = db.GetDbContext();
var toLoad = uow.GuildConfigs.IncludeEverything().FirstOrDefault(x => x.GuildId == guildId);
if (toLoad is null)
{
await uow.ForGuildId(guildId);
toLoad = uow.GuildConfigs.IncludeEverything().FirstOrDefault(x => x.GuildId == guildId);
}

await cache.SetGuildConfigCache(guildId, toLoad!);
return toLoad!;
}

/// <summary>
/// Updates the guild configuration.
/// </summary>
public async Task UpdateGuildConfig(ulong guildId, GuildConfig toUpdate)
{
await using var uow = db.GetDbContext();
var exists = await cache.GetGuildConfigCache(guildId);

if (exists is not null)
{
var properties = typeof(GuildConfig).GetProperties();
foreach (var property in properties)
{
var oldValue = property.GetValue(exists);
var newValue = property.GetValue(toUpdate);

if (newValue != null && !newValue.Equals(oldValue))
{
property.SetValue(exists, newValue);
}
}

await cache.SetGuildConfigCache(guildId, exists);
uow.GuildConfigs.Update(exists);
await uow.SaveChangesAsync();
}
else
{
var config = uow.GuildConfigs.IncludeEverything().FirstOrDefault(x => x.Id == toUpdate.Id);

if (config != null)
{
var properties = typeof(GuildConfig).GetProperties();
foreach (var property in properties)
{
var oldValue = property.GetValue(config);
var newValue = property.GetValue(toUpdate);

if (newValue != null && !newValue.Equals(oldValue))
{
property.SetValue(config, newValue);
}
}

await cache.SetGuildConfigCache(guildId, config);
uow.GuildConfigs.Update(config);
await uow.SaveChangesAsync();
}
}
}
}
28 changes: 28 additions & 0 deletions Mewdeko.Api/Services/RedisCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ public class RedisCache
{
private readonly string redisKey;

private readonly JsonSerializerSettings settings = new()
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};

/// <summary>
/// Initializes a new instance of the <see cref="RedisCache" /> class.
/// </summary>
Expand Down Expand Up @@ -48,6 +53,29 @@ await db.StringSetAsync($"{redisKey}_{guildId}_{userId}_afk", JsonConvert.Serial
}
}

/// <summary>
/// Caches config for a guild.
/// </summary>
/// <param name="id">The guild ID.</param>
/// <param name="config">The config to cache.</param>
public async Task SetGuildConfigCache(ulong id, GuildConfig config)
{
var db = Redis.GetDatabase();
await db.StringSetAsync($"{redisKey}_guildconfig_{id}", JsonConvert.SerializeObject(config, settings));
}

/// <summary>
/// Retrieves config for a guild.
/// </summary>
/// <param name="id">The guild ID.</param>
/// <returns>If successfull, the guild config, if not, null.</returns>
public async Task<GuildConfig?> GetGuildConfigCache(ulong id)
{
var db = Redis.GetDatabase();
var result = await db.StringGetAsync($"{redisKey}_guildconfig_{id}");
return result.HasValue ? JsonConvert.DeserializeObject<GuildConfig>(result, settings) : null;

Check warning on line 76 in Mewdeko.Api/Services/RedisCache.cs

View workflow job for this annotation

GitHub Actions / Qodana for .NET

Possible null reference argument for a parameter.

Possible null reference argument for parameter 'value' in 'Newtonsoft.Json.JsonConvert.DeserializeObject'
}

/// <summary>
/// Retrieves a users afk status.
/// </summary>
Expand Down
15 changes: 0 additions & 15 deletions src/Mewdeko.Database/Extensions/MusicExtensions.cs

This file was deleted.

23 changes: 0 additions & 23 deletions src/Mewdeko.Database/Extensions/MusicPlayerExtensions.cs

This file was deleted.

13 changes: 0 additions & 13 deletions src/Mewdeko.Database/Extensions/NicknameExtensions.cs

This file was deleted.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 0 additions & 14 deletions src/Mewdeko.Database/Models/FilterChannelId.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,5 @@ public override bool Equals(object obj) =>
obj is FilterInvitesChannelIds f
&& f.ChannelId == ChannelId;

public override int GetHashCode() => ChannelId.GetHashCode();
}

public class FilterWordsChannelIds : DbEntity
{
public ulong ChannelId { get; set; }

[ForeignKey("GuildConfigId")]
public int GuildConfigId { get; set; }

public override bool Equals(object obj) =>
obj is FilterWordsChannelIds f
&& f.ChannelId == ChannelId;

public override int GetHashCode() => ChannelId.GetHashCode();
}
17 changes: 17 additions & 0 deletions src/Mewdeko.Database/Models/FilterWordsChannelIds.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.ComponentModel.DataAnnotations.Schema;

namespace Mewdeko.Database.Models;

public class FilterWordsChannelIds : DbEntity
{
public ulong ChannelId { get; set; }

[ForeignKey("GuildConfigId")]
public int GuildConfigId { get; set; }

public override bool Equals(object obj) =>
obj is FilterWordsChannelIds f
&& f.ChannelId == ChannelId;

public override int GetHashCode() => ChannelId.GetHashCode();
}

0 comments on commit 16dd856

Please sign in to comment.