[backend] Refactor inverse properties; add projectable computed properties to the User class

This commit is contained in:
Laura Hausmann 2024-02-02 22:59:17 +01:00
parent b015c464dd
commit af7a776337
No known key found for this signature in database
GPG key ID: D044E84C5BE01605
64 changed files with 256 additions and 241 deletions

View file

@ -1,15 +1,12 @@
using Iceshrimp.Backend.Controllers.Attributes;
using Iceshrimp.Backend.Controllers.Mastodon.Renderers; using Iceshrimp.Backend.Controllers.Mastodon.Renderers;
using Iceshrimp.Backend.Controllers.Mastodon.Schemas; using Iceshrimp.Backend.Controllers.Mastodon.Schemas;
using Iceshrimp.Backend.Controllers.Mastodon.Schemas.Entities; using Iceshrimp.Backend.Controllers.Mastodon.Schemas.Entities;
using Iceshrimp.Backend.Core.Database; using Iceshrimp.Backend.Core.Database;
using Iceshrimp.Backend.Core.Database.Tables; using Iceshrimp.Backend.Core.Database.Tables;
using Iceshrimp.Backend.Core.Extensions; using Iceshrimp.Backend.Core.Extensions;
using Iceshrimp.Backend.Core.Helpers;
using Iceshrimp.Backend.Core.Middleware; using Iceshrimp.Backend.Core.Middleware;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.RateLimiting; using Microsoft.AspNetCore.RateLimiting;
using Microsoft.EntityFrameworkCore;
namespace Iceshrimp.Backend.Controllers.Mastodon; namespace Iceshrimp.Backend.Controllers.Mastodon;
@ -28,13 +25,13 @@ public class MastodonTimelineController(DatabaseContext db, NoteRenderer noteRen
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable<Status>))] [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable<Status>))]
public async Task<IActionResult> GetHomeTimeline() { public async Task<IActionResult> GetHomeTimeline() {
var user = HttpContext.GetOauthUser() ?? throw new GracefulException("Failed to get user from HttpContext"); var user = HttpContext.GetOauthUser() ?? throw new GracefulException("Failed to get user from HttpContext");
var notes = db.Notes var res = await db.Notes
.WithIncludes() .WithIncludes()
.IsFollowedBy(user) .FilterByFollowingAndOwn(user)
.OrderByIdDesc() .OrderByIdDesc()
.Take(40); .Take(40)
.RenderAllForMastodonAsync(noteRenderer);
var res = await notes.RenderAllForMastodonAsync(noteRenderer);
return Ok(res); return Ok(res);
} }
@ -43,13 +40,13 @@ public class MastodonTimelineController(DatabaseContext db, NoteRenderer noteRen
[Produces("application/json")] [Produces("application/json")]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable<Status>))] [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable<Status>))]
public async Task<IActionResult> GetPublicTimeline() { public async Task<IActionResult> GetPublicTimeline() {
var notes = db.Notes var res = await db.Notes
.WithIncludes() .WithIncludes()
.HasVisibility(Note.NoteVisibility.Public) .HasVisibility(Note.NoteVisibility.Public)
.OrderByIdDesc() .OrderByIdDesc()
.Take(40); .Take(40)
.RenderAllForMastodonAsync(noteRenderer);
var res = await notes.RenderAllForMastodonAsync(noteRenderer);
return Ok(res); return Ok(res);
} }
} }

View file

@ -1,4 +1,5 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using EntityFrameworkCore.Projectables.Infrastructure;
using Iceshrimp.Backend.Core.Configuration; using Iceshrimp.Backend.Core.Configuration;
using Iceshrimp.Backend.Core.Database.Tables; using Iceshrimp.Backend.Core.Database.Tables;
using Microsoft.AspNetCore.DataProtection.EntityFrameworkCore; using Microsoft.AspNetCore.DataProtection.EntityFrameworkCore;
@ -106,6 +107,9 @@ public class DatabaseContext(DbContextOptions<DatabaseContext> options)
public static void Configure(DbContextOptionsBuilder optionsBuilder, NpgsqlDataSource dataSource) { public static void Configure(DbContextOptionsBuilder optionsBuilder, NpgsqlDataSource dataSource) {
optionsBuilder.UseNpgsql(dataSource); optionsBuilder.UseNpgsql(dataSource);
optionsBuilder.UseProjectables(options => {
options.CompatibilityMode(CompatibilityMode.Limited);
});
} }
protected override void OnModelCreating(ModelBuilder modelBuilder) { protected override void OnModelCreating(ModelBuilder modelBuilder) {
@ -348,9 +352,9 @@ public class DatabaseContext(DbContextOptions<DatabaseContext> options)
entity.Property(e => e.FollowerSharedInbox).HasComment("[Denormalized]"); entity.Property(e => e.FollowerSharedInbox).HasComment("[Denormalized]");
entity.Property(e => e.RequestId).HasComment("id of Follow Activity."); entity.Property(e => e.RequestId).HasComment("id of Follow Activity.");
entity.HasOne(d => d.Followee).WithMany(p => p.FollowRequestFollowees); entity.HasOne(d => d.Followee).WithMany(p => p.IncomingFollowRequests);
entity.HasOne(d => d.Follower).WithMany(p => p.FollowRequestFollowers); entity.HasOne(d => d.Follower).WithMany(p => p.OutgoingFollowRequests);
}); });
modelBuilder.Entity<Following>(entity => { modelBuilder.Entity<Following>(entity => {
@ -364,9 +368,9 @@ public class DatabaseContext(DbContextOptions<DatabaseContext> options)
entity.Property(e => e.FollowerInbox).HasComment("[Denormalized]"); entity.Property(e => e.FollowerInbox).HasComment("[Denormalized]");
entity.Property(e => e.FollowerSharedInbox).HasComment("[Denormalized]"); entity.Property(e => e.FollowerSharedInbox).HasComment("[Denormalized]");
entity.HasOne(d => d.Followee).WithMany(p => p.FollowingFollowees); entity.HasOne(d => d.Followee).WithMany(p => p.IncomingFollowRelationships);
entity.HasOne(d => d.Follower).WithMany(p => p.FollowingFollowers); entity.HasOne(d => d.Follower).WithMany(p => p.OutgoingFollowRelationships);
}); });
modelBuilder.Entity<GalleryLike>(entity => { modelBuilder.Entity<GalleryLike>(entity => {

View file

@ -58,14 +58,14 @@ public class AbuseUserReport {
[Column("forwarded")] public bool Forwarded { get; set; } [Column("forwarded")] public bool Forwarded { get; set; }
[ForeignKey("AssigneeId")] [ForeignKey("AssigneeId")]
[InverseProperty("AbuseUserReportAssignees")] [InverseProperty(nameof(User.AbuseUserReportAssignees))]
public virtual User? Assignee { get; set; } public virtual User? Assignee { get; set; }
[ForeignKey("ReporterId")] [ForeignKey("ReporterId")]
[InverseProperty("AbuseUserReportReporters")] [InverseProperty(nameof(User.AbuseUserReportReporters))]
public virtual User Reporter { get; set; } = null!; public virtual User Reporter { get; set; } = null!;
[ForeignKey("TargetUserId")] [ForeignKey("TargetUserId")]
[InverseProperty("AbuseUserReportTargetUsers")] [InverseProperty(nameof(User.AbuseUserReportTargetUsers))]
public virtual User TargetUser { get; set; } = null!; public virtual User TargetUser { get; set; } = null!;
} }

View file

@ -51,13 +51,13 @@ public class AccessToken {
[Column("fetched")] public bool Fetched { get; set; } [Column("fetched")] public bool Fetched { get; set; }
[ForeignKey("AppId")] [ForeignKey("AppId")]
[InverseProperty("AccessTokens")] [InverseProperty(nameof(Tables.App.AccessTokens))]
public virtual App? App { get; set; } public virtual App? App { get; set; }
[InverseProperty("AppAccessToken")] [InverseProperty(nameof(Notification.AppAccessToken))]
public virtual ICollection<Notification> Notifications { get; set; } = new List<Notification>(); public virtual ICollection<Notification> Notifications { get; set; } = new List<Notification>();
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("AccessTokens")] [InverseProperty(nameof(Tables.User.AccessTokens))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
} }

View file

@ -36,6 +36,6 @@ public class Announcement {
[Column("isGoodNews")] public bool IsGoodNews { get; set; } [Column("isGoodNews")] public bool IsGoodNews { get; set; }
[InverseProperty("Announcement")] [InverseProperty(nameof(AnnouncementRead.Announcement))]
public virtual ICollection<AnnouncementRead> AnnouncementReads { get; set; } = new List<AnnouncementRead>(); public virtual ICollection<AnnouncementRead> AnnouncementReads { get; set; } = new List<AnnouncementRead>();
} }

View file

@ -27,10 +27,10 @@ public class AnnouncementRead {
public DateTime CreatedAt { get; set; } public DateTime CreatedAt { get; set; }
[ForeignKey("AnnouncementId")] [ForeignKey("AnnouncementId")]
[InverseProperty("AnnouncementReads")] [InverseProperty(nameof(Tables.Announcement.AnnouncementReads))]
public virtual Announcement Announcement { get; set; } = null!; public virtual Announcement Announcement { get; set; } = null!;
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("AnnouncementReads")] [InverseProperty(nameof(Tables.User.AnnouncementReads))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
} }

View file

@ -68,15 +68,15 @@ public class Antenna {
public string Instances { get; set; } = null!; public string Instances { get; set; } = null!;
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("Antennas")] [InverseProperty(nameof(Tables.User.Antennas))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
[ForeignKey("UserGroupMemberId")] [ForeignKey("UserGroupMemberId")]
[InverseProperty("Antennas")] [InverseProperty(nameof(Tables.UserGroupMember.Antennas))]
public virtual UserGroupMember? UserGroupMember { get; set; } public virtual UserGroupMember? UserGroupMember { get; set; }
[ForeignKey("UserListId")] [ForeignKey("UserListId")]
[InverseProperty("Antennas")] [InverseProperty(nameof(Tables.UserList.Antennas))]
public virtual UserList? UserList { get; set; } public virtual UserList? UserList { get; set; }
[PgName("antenna_src_enum")] [PgName("antenna_src_enum")]

View file

@ -61,13 +61,13 @@ public class App {
[StringLength(512)] [StringLength(512)]
public string? CallbackUrl { get; set; } public string? CallbackUrl { get; set; }
[InverseProperty("App")] [InverseProperty(nameof(AccessToken.App))]
public virtual ICollection<AccessToken> AccessTokens { get; set; } = new List<AccessToken>(); public virtual ICollection<AccessToken> AccessTokens { get; set; } = new List<AccessToken>();
[InverseProperty("App")] [InverseProperty(nameof(AuthSession.App))]
public virtual ICollection<AuthSession> AuthSessions { get; set; } = new List<AuthSession>(); public virtual ICollection<AuthSession> AuthSessions { get; set; } = new List<AuthSession>();
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("Apps")] [InverseProperty(nameof(Tables.User.Apps))]
public virtual User? User { get; set; } public virtual User? User { get; set; }
} }

View file

@ -40,6 +40,6 @@ public class AttestationChallenge {
public bool RegistrationChallenge { get; set; } public bool RegistrationChallenge { get; set; }
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("AttestationChallenges")] [InverseProperty(nameof(Tables.User.AttestationChallenges))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
} }

View file

@ -25,10 +25,10 @@ public class AuthSession {
[Column("appId")] [StringLength(32)] public string AppId { get; set; } = null!; [Column("appId")] [StringLength(32)] public string AppId { get; set; } = null!;
[ForeignKey("AppId")] [ForeignKey("AppId")]
[InverseProperty("AuthSessions")] [InverseProperty(nameof(Tables.App.AuthSessions))]
public virtual App App { get; set; } = null!; public virtual App App { get; set; } = null!;
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("AuthSessions")] [InverseProperty(nameof(Tables.User.AuthSessions))]
public virtual User? User { get; set; } public virtual User? User { get; set; }
} }

View file

@ -36,10 +36,10 @@ public class Blocking {
public string BlockerId { get; set; } = null!; public string BlockerId { get; set; } = null!;
[ForeignKey("BlockeeId")] [ForeignKey("BlockeeId")]
[InverseProperty("BlockingBlockees")] [InverseProperty(nameof(User.BlockingBlockees))]
public virtual User Blockee { get; set; } = null!; public virtual User Blockee { get; set; } = null!;
[ForeignKey("BlockerId")] [ForeignKey("BlockerId")]
[InverseProperty("BlockingBlockers")] [InverseProperty(nameof(User.BlockingBlockers))]
public virtual User Blocker { get; set; } = null!; public virtual User Blocker { get; set; } = null!;
} }

View file

@ -65,18 +65,18 @@ public class Channel {
public int UsersCount { get; set; } public int UsersCount { get; set; }
[ForeignKey("BannerId")] [ForeignKey("BannerId")]
[InverseProperty("Channels")] [InverseProperty(nameof(DriveFile.Channels))]
public virtual DriveFile? Banner { get; set; } public virtual DriveFile? Banner { get; set; }
[InverseProperty("Followee")] [InverseProperty(nameof(ChannelFollowing.Followee))]
public virtual ICollection<ChannelFollowing> ChannelFollowings { get; set; } = new List<ChannelFollowing>(); public virtual ICollection<ChannelFollowing> ChannelFollowings { get; set; } = new List<ChannelFollowing>();
[InverseProperty("Channel")] [InverseProperty(nameof(ChannelNotePin.Channel))]
public virtual ICollection<ChannelNotePin> ChannelNotePins { get; set; } = new List<ChannelNotePin>(); public virtual ICollection<ChannelNotePin> ChannelNotePins { get; set; } = new List<ChannelNotePin>();
[InverseProperty("Channel")] public virtual ICollection<Note> Notes { get; set; } = new List<Note>(); [InverseProperty(nameof(Note.Channel))] public virtual ICollection<Note> Notes { get; set; } = new List<Note>();
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("Channels")] [InverseProperty(nameof(Tables.User.Channels))]
public virtual User? User { get; set; } public virtual User? User { get; set; }
} }

View file

@ -36,10 +36,10 @@ public class ChannelFollowing {
public string FollowerId { get; set; } = null!; public string FollowerId { get; set; } = null!;
[ForeignKey("FolloweeId")] [ForeignKey("FolloweeId")]
[InverseProperty("ChannelFollowings")] [InverseProperty(nameof(Channel.ChannelFollowings))]
public virtual Channel Followee { get; set; } = null!; public virtual Channel Followee { get; set; } = null!;
[ForeignKey("FollowerId")] [ForeignKey("FollowerId")]
[InverseProperty("ChannelFollowings")] [InverseProperty(nameof(User.ChannelFollowings))]
public virtual User Follower { get; set; } = null!; public virtual User Follower { get; set; } = null!;
} }

View file

@ -26,10 +26,10 @@ public class ChannelNotePin {
[Column("noteId")] [StringLength(32)] public string NoteId { get; set; } = null!; [Column("noteId")] [StringLength(32)] public string NoteId { get; set; } = null!;
[ForeignKey("ChannelId")] [ForeignKey("ChannelId")]
[InverseProperty("ChannelNotePins")] [InverseProperty(nameof(Tables.Channel.ChannelNotePins))]
public virtual Channel Channel { get; set; } = null!; public virtual Channel Channel { get; set; } = null!;
[ForeignKey("NoteId")] [ForeignKey("NoteId")]
[InverseProperty("ChannelNotePins")] [InverseProperty(nameof(Tables.Note.ChannelNotePins))]
public virtual Note Note { get; set; } = null!; public virtual Note Note { get; set; } = null!;
} }

View file

@ -41,9 +41,9 @@ public class Clip {
[StringLength(2048)] [StringLength(2048)]
public string? Description { get; set; } public string? Description { get; set; }
[InverseProperty("Clip")] public virtual ICollection<ClipNote> ClipNotes { get; set; } = new List<ClipNote>(); [InverseProperty(nameof(ClipNote.Clip))] public virtual ICollection<ClipNote> ClipNotes { get; set; } = new List<ClipNote>();
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("Clips")] [InverseProperty(nameof(Tables.User.Clips))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
} }

View file

@ -29,10 +29,10 @@ public class ClipNote {
public string ClipId { get; set; } = null!; public string ClipId { get; set; } = null!;
[ForeignKey("ClipId")] [ForeignKey("ClipId")]
[InverseProperty("ClipNotes")] [InverseProperty(nameof(Tables.Clip.ClipNotes))]
public virtual Clip Clip { get; set; } = null!; public virtual Clip Clip { get; set; } = null!;
[ForeignKey("NoteId")] [ForeignKey("NoteId")]
[InverseProperty("ClipNotes")] [InverseProperty(nameof(Tables.Note.ClipNotes))]
public virtual Note Note { get; set; } = null!; public virtual Note Note { get; set; } = null!;
} }

View file

@ -165,22 +165,22 @@ public class DriveFile {
[StringLength(128)] [StringLength(128)]
public string? RequestIp { get; set; } public string? RequestIp { get; set; }
[InverseProperty("Banner")] public virtual ICollection<Channel> Channels { get; set; } = new List<Channel>(); [InverseProperty(nameof(Channel.Banner))] public virtual ICollection<Channel> Channels { get; set; } = new List<Channel>();
[ForeignKey("FolderId")] [ForeignKey("FolderId")]
[InverseProperty("DriveFiles")] [InverseProperty(nameof(DriveFolder.DriveFiles))]
public virtual DriveFolder? Folder { get; set; } public virtual DriveFolder? Folder { get; set; }
[InverseProperty("File")] [InverseProperty(nameof(MessagingMessage.File))]
public virtual ICollection<MessagingMessage> MessagingMessages { get; set; } = new List<MessagingMessage>(); public virtual ICollection<MessagingMessage> MessagingMessages { get; set; } = new List<MessagingMessage>();
[InverseProperty("EyeCatchingImage")] public virtual ICollection<Page> Pages { get; set; } = new List<Page>(); [InverseProperty(nameof(Page.EyeCatchingImage))] public virtual ICollection<Page> Pages { get; set; } = new List<Page>();
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("DriveFiles")] [InverseProperty(nameof(Tables.User.DriveFiles))]
public virtual User? User { get; set; } public virtual User? User { get; set; }
[InverseProperty("Avatar")] public virtual User? UserAvatar { get; set; } [InverseProperty(nameof(Tables.User.Avatar))] public virtual User? UserAvatar { get; set; }
[InverseProperty("Banner")] public virtual User? UserBanner { get; set; } [InverseProperty(nameof(Tables.User.Banner))] public virtual User? UserBanner { get; set; }
} }

View file

@ -41,16 +41,16 @@ public class DriveFolder {
[StringLength(32)] [StringLength(32)]
public string? ParentId { get; set; } public string? ParentId { get; set; }
[InverseProperty("Folder")] public virtual ICollection<DriveFile> DriveFiles { get; set; } = new List<DriveFile>(); [InverseProperty(nameof(DriveFile.Folder))] public virtual ICollection<DriveFile> DriveFiles { get; set; } = new List<DriveFile>();
[InverseProperty("Parent")] [InverseProperty(nameof(Parent))]
public virtual ICollection<DriveFolder> InverseParent { get; set; } = new List<DriveFolder>(); public virtual ICollection<DriveFolder> InverseParent { get; set; } = new List<DriveFolder>();
[ForeignKey("ParentId")] [ForeignKey("ParentId")]
[InverseProperty("InverseParent")] [InverseProperty(nameof(InverseParent))]
public virtual DriveFolder? Parent { get; set; } public virtual DriveFolder? Parent { get; set; }
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("DriveFolders")] [InverseProperty(nameof(Tables.User.DriveFolders))]
public virtual User? User { get; set; } public virtual User? User { get; set; }
} }

View file

@ -84,13 +84,13 @@ public class FollowRequest {
public string? FolloweeSharedInbox { get; set; } public string? FolloweeSharedInbox { get; set; }
[ForeignKey("FolloweeId")] [ForeignKey("FolloweeId")]
[InverseProperty("FollowRequestFollowees")] [InverseProperty(nameof(User.IncomingFollowRequests))]
public virtual User Followee { get; set; } = null!; public virtual User Followee { get; set; } = null!;
[ForeignKey("FollowerId")] [ForeignKey("FollowerId")]
[InverseProperty("FollowRequestFollowers")] [InverseProperty(nameof(User.OutgoingFollowRequests))]
public virtual User Follower { get; set; } = null!; public virtual User Follower { get; set; } = null!;
[InverseProperty("FollowRequest")] [InverseProperty(nameof(Notification.FollowRequest))]
public virtual ICollection<Notification> Notifications { get; set; } = new List<Notification>(); public virtual ICollection<Notification> Notifications { get; set; } = new List<Notification>();
} }

View file

@ -80,10 +80,10 @@ public class Following {
public string? FolloweeSharedInbox { get; set; } public string? FolloweeSharedInbox { get; set; }
[ForeignKey("FolloweeId")] [ForeignKey("FolloweeId")]
[InverseProperty("FollowingFollowees")] [InverseProperty(nameof(User.IncomingFollowRelationships))]
public virtual User Followee { get; set; } = null!; public virtual User Followee { get; set; } = null!;
[ForeignKey("FollowerId")] [ForeignKey("FollowerId")]
[InverseProperty("FollowingFollowers")] [InverseProperty(nameof(User.OutgoingFollowRelationships))]
public virtual User Follower { get; set; } = null!; public virtual User Follower { get; set; } = null!;
} }

View file

@ -20,10 +20,10 @@ public class GalleryLike {
[Column("postId")] [StringLength(32)] public string PostId { get; set; } = null!; [Column("postId")] [StringLength(32)] public string PostId { get; set; } = null!;
[ForeignKey("PostId")] [ForeignKey("PostId")]
[InverseProperty("GalleryLikes")] [InverseProperty(nameof(GalleryPost.GalleryLikes))]
public virtual GalleryPost Post { get; set; } = null!; public virtual GalleryPost Post { get; set; } = null!;
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("GalleryLikes")] [InverseProperty(nameof(Tables.User.GalleryLikes))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
} }

View file

@ -57,10 +57,10 @@ public class GalleryPost {
[Column("tags", TypeName = "character varying(128)[]")] [Column("tags", TypeName = "character varying(128)[]")]
public List<string> Tags { get; set; } = null!; public List<string> Tags { get; set; } = null!;
[InverseProperty("Post")] [InverseProperty(nameof(GalleryLike.Post))]
public virtual ICollection<GalleryLike> GalleryLikes { get; set; } = new List<GalleryLike>(); public virtual ICollection<GalleryLike> GalleryLikes { get; set; } = new List<GalleryLike>();
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("GalleryPosts")] [InverseProperty(nameof(Tables.User.GalleryPosts))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
} }

View file

@ -15,6 +15,6 @@ public class HtmlNoteCacheEntry {
[Column("content")] public string? Content { get; set; } [Column("content")] public string? Content { get; set; }
[ForeignKey("NoteId")] [ForeignKey("NoteId")]
[InverseProperty("HtmlNoteCacheEntry")] [InverseProperty(nameof(Tables.Note.HtmlNoteCacheEntry))]
public virtual Note Note { get; set; } = null!; public virtual Note Note { get; set; } = null!;
} }

View file

@ -17,6 +17,6 @@ public class HtmlUserCacheEntry {
[Column("fields", TypeName = "jsonb")] public string Fields { get; set; } = null!; [Column("fields", TypeName = "jsonb")] public string Fields { get; set; } = null!;
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("HtmlUserCacheEntry")] [InverseProperty(nameof(Tables.User.HtmlUserCacheEntry))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
} }

View file

@ -54,18 +54,18 @@ public class MessagingMessage {
[Column("uri")] [StringLength(512)] public string? Uri { get; set; } [Column("uri")] [StringLength(512)] public string? Uri { get; set; }
[ForeignKey("FileId")] [ForeignKey("FileId")]
[InverseProperty("MessagingMessages")] [InverseProperty(nameof(DriveFile.MessagingMessages))]
public virtual DriveFile? File { get; set; } public virtual DriveFile? File { get; set; }
[ForeignKey("GroupId")] [ForeignKey("GroupId")]
[InverseProperty("MessagingMessages")] [InverseProperty(nameof(UserGroup.MessagingMessages))]
public virtual UserGroup? Group { get; set; } public virtual UserGroup? Group { get; set; }
[ForeignKey("RecipientId")] [ForeignKey("RecipientId")]
[InverseProperty("MessagingMessageRecipients")] [InverseProperty(nameof(Tables.User.MessagingMessageRecipients))]
public virtual User? Recipient { get; set; } public virtual User? Recipient { get; set; }
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("MessagingMessageUsers")] [InverseProperty(nameof(Tables.User.MessagingMessageUsers))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
} }

View file

@ -25,6 +25,6 @@ public class ModerationLog {
[Column("info", TypeName = "jsonb")] public string Info { get; set; } = null!; [Column("info", TypeName = "jsonb")] public string Info { get; set; } = null!;
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("ModerationLogs")] [InverseProperty(nameof(Tables.User.ModerationLogs))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
} }

View file

@ -39,10 +39,10 @@ public class Muting {
[Column("expiresAt")] public DateTime? ExpiresAt { get; set; } [Column("expiresAt")] public DateTime? ExpiresAt { get; set; }
[ForeignKey("MuteeId")] [ForeignKey("MuteeId")]
[InverseProperty("MutingMutees")] [InverseProperty(nameof(User.MutingMutees))]
public virtual User Mutee { get; set; } = null!; public virtual User Mutee { get; set; } = null!;
[ForeignKey("MuterId")] [ForeignKey("MuterId")]
[InverseProperty("MutingMuters")] [InverseProperty(nameof(User.MutingMuters))]
public virtual User Muter { get; set; } = null!; public virtual User Muter { get; set; } = null!;
} }

View file

@ -173,56 +173,56 @@ public class Note {
public DateTime? UpdatedAt { get; set; } public DateTime? UpdatedAt { get; set; }
[ForeignKey("ChannelId")] [ForeignKey("ChannelId")]
[InverseProperty("Notes")] [InverseProperty(nameof(Tables.Channel.Notes))]
public virtual Channel? Channel { get; set; } public virtual Channel? Channel { get; set; }
[InverseProperty("Note")] [InverseProperty(nameof(ChannelNotePin.Note))]
public virtual ICollection<ChannelNotePin> ChannelNotePins { get; set; } = new List<ChannelNotePin>(); public virtual ICollection<ChannelNotePin> ChannelNotePins { get; set; } = new List<ChannelNotePin>();
[InverseProperty("Note")] public virtual ICollection<ClipNote> ClipNotes { get; set; } = new List<ClipNote>(); [InverseProperty(nameof(ClipNote.Note))] public virtual ICollection<ClipNote> ClipNotes { get; set; } = new List<ClipNote>();
[InverseProperty("Note")] public virtual HtmlNoteCacheEntry? HtmlNoteCacheEntry { get; set; } [InverseProperty(nameof(Tables.HtmlNoteCacheEntry.Note))] public virtual HtmlNoteCacheEntry? HtmlNoteCacheEntry { get; set; }
[InverseProperty("Renote")] public virtual ICollection<Note> InverseRenote { get; set; } = new List<Note>(); [InverseProperty(nameof(Renote))] public virtual ICollection<Note> InverseRenote { get; set; } = new List<Note>();
[InverseProperty("Reply")] public virtual ICollection<Note> InverseReply { get; set; } = new List<Note>(); [InverseProperty(nameof(Reply))] public virtual ICollection<Note> InverseReply { get; set; } = new List<Note>();
[InverseProperty("Note")] public virtual ICollection<NoteEdit> NoteEdits { get; set; } = new List<NoteEdit>(); [InverseProperty(nameof(NoteEdit.Note))] public virtual ICollection<NoteEdit> NoteEdits { get; set; } = new List<NoteEdit>();
[InverseProperty("Note")] [InverseProperty(nameof(NoteFavorite.Note))]
public virtual ICollection<NoteFavorite> NoteFavorites { get; set; } = new List<NoteFavorite>(); public virtual ICollection<NoteFavorite> NoteFavorites { get; set; } = new List<NoteFavorite>();
[InverseProperty("Note")] [InverseProperty(nameof(NoteReaction.Note))]
public virtual ICollection<NoteReaction> NoteReactions { get; set; } = new List<NoteReaction>(); public virtual ICollection<NoteReaction> NoteReactions { get; set; } = new List<NoteReaction>();
[InverseProperty("Note")] public virtual ICollection<NoteUnread> NoteUnreads { get; set; } = new List<NoteUnread>(); [InverseProperty(nameof(NoteUnread.Note))] public virtual ICollection<NoteUnread> NoteUnreads { get; set; } = new List<NoteUnread>();
[InverseProperty("Note")] [InverseProperty(nameof(NoteWatching.Note))]
public virtual ICollection<NoteWatching> NoteWatchings { get; set; } = new List<NoteWatching>(); public virtual ICollection<NoteWatching> NoteWatchings { get; set; } = new List<NoteWatching>();
[InverseProperty("Note")] [InverseProperty(nameof(Notification.Note))]
public virtual ICollection<Notification> Notifications { get; set; } = new List<Notification>(); public virtual ICollection<Notification> Notifications { get; set; } = new List<Notification>();
[InverseProperty("Note")] public virtual Poll? Poll { get; set; } [InverseProperty(nameof(Tables.Poll.Note))] public virtual Poll? Poll { get; set; }
[InverseProperty("Note")] public virtual ICollection<PollVote> PollVotes { get; set; } = new List<PollVote>(); [InverseProperty(nameof(PollVote.Note))] public virtual ICollection<PollVote> PollVotes { get; set; } = new List<PollVote>();
[InverseProperty("Note")] public virtual PromoNote? PromoNote { get; set; } [InverseProperty(nameof(Tables.PromoNote.Note))] public virtual PromoNote? PromoNote { get; set; }
[InverseProperty("Note")] public virtual ICollection<PromoRead> PromoReads { get; set; } = new List<PromoRead>(); [InverseProperty(nameof(PromoRead.Note))] public virtual ICollection<PromoRead> PromoReads { get; set; } = new List<PromoRead>();
[ForeignKey("RenoteId")] [ForeignKey("RenoteId")]
[InverseProperty("InverseRenote")] [InverseProperty(nameof(InverseRenote))]
public virtual Note? Renote { get; set; } public virtual Note? Renote { get; set; }
[ForeignKey("ReplyId")] [ForeignKey("ReplyId")]
[InverseProperty("InverseReply")] [InverseProperty(nameof(InverseReply))]
public virtual Note? Reply { get; set; } public virtual Note? Reply { get; set; }
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("Notes")] [InverseProperty(nameof(Tables.User.Notes))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
[InverseProperty("Note")] [InverseProperty(nameof(UserNotePin.Note))]
public virtual ICollection<UserNotePin> UserNotePins { get; set; } = new List<UserNotePin>(); public virtual ICollection<UserNotePin> UserNotePins { get; set; } = new List<UserNotePin>();
} }

View file

@ -33,6 +33,6 @@ public class NoteEdit {
public DateTime UpdatedAt { get; set; } public DateTime UpdatedAt { get; set; }
[ForeignKey("NoteId")] [ForeignKey("NoteId")]
[InverseProperty("NoteEdits")] [InverseProperty(nameof(Tables.Note.NoteEdits))]
public virtual Note Note { get; set; } = null!; public virtual Note Note { get; set; } = null!;
} }

View file

@ -24,10 +24,10 @@ public class NoteFavorite {
[Column("noteId")] [StringLength(32)] public string NoteId { get; set; } = null!; [Column("noteId")] [StringLength(32)] public string NoteId { get; set; } = null!;
[ForeignKey("NoteId")] [ForeignKey("NoteId")]
[InverseProperty("NoteFavorites")] [InverseProperty(nameof(Tables.Note.NoteFavorites))]
public virtual Note Note { get; set; } = null!; public virtual Note Note { get; set; } = null!;
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("NoteFavorites")] [InverseProperty(nameof(Tables.User.NoteFavorites))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
} }

View file

@ -30,10 +30,10 @@ public class NoteReaction {
public string Reaction { get; set; } = null!; public string Reaction { get; set; } = null!;
[ForeignKey("NoteId")] [ForeignKey("NoteId")]
[InverseProperty("NoteReactions")] [InverseProperty(nameof(Tables.Note.NoteReactions))]
public virtual Note Note { get; set; } = null!; public virtual Note Note { get; set; } = null!;
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("NoteReactions")] [InverseProperty(nameof(Tables.User.NoteReactions))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
} }

View file

@ -23,6 +23,6 @@ public class NoteThreadMuting {
public string ThreadId { get; set; } = null!; public string ThreadId { get; set; } = null!;
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("NoteThreadMutings")] [InverseProperty(nameof(Tables.User.NoteThreadMutings))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
} }

View file

@ -41,10 +41,10 @@ public class NoteUnread {
public string? NoteChannelId { get; set; } public string? NoteChannelId { get; set; }
[ForeignKey("NoteId")] [ForeignKey("NoteId")]
[InverseProperty("NoteUnreads")] [InverseProperty(nameof(Tables.Note.NoteUnreads))]
public virtual Note Note { get; set; } = null!; public virtual Note Note { get; set; } = null!;
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("NoteUnreads")] [InverseProperty(nameof(Tables.User.NoteUnreads))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
} }

View file

@ -44,10 +44,10 @@ public class NoteWatching {
public string NoteUserId { get; set; } = null!; public string NoteUserId { get; set; } = null!;
[ForeignKey("NoteId")] [ForeignKey("NoteId")]
[InverseProperty("NoteWatchings")] [InverseProperty(nameof(Tables.Note.NoteWatchings))]
public virtual Note Note { get; set; } = null!; public virtual Note Note { get; set; } = null!;
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("NoteWatchings")] [InverseProperty(nameof(Tables.User.NoteWatchings))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
} }

View file

@ -79,27 +79,27 @@ public class Notification {
public string? AppAccessTokenId { get; set; } public string? AppAccessTokenId { get; set; }
[ForeignKey("AppAccessTokenId")] [ForeignKey("AppAccessTokenId")]
[InverseProperty("Notifications")] [InverseProperty(nameof(AccessToken.Notifications))]
public virtual AccessToken? AppAccessToken { get; set; } public virtual AccessToken? AppAccessToken { get; set; }
[ForeignKey("FollowRequestId")] [ForeignKey("FollowRequestId")]
[InverseProperty("Notifications")] [InverseProperty(nameof(Tables.FollowRequest.Notifications))]
public virtual FollowRequest? FollowRequest { get; set; } public virtual FollowRequest? FollowRequest { get; set; }
[ForeignKey("NoteId")] [ForeignKey("NoteId")]
[InverseProperty("Notifications")] [InverseProperty(nameof(Tables.Note.Notifications))]
public virtual Note? Note { get; set; } public virtual Note? Note { get; set; }
[ForeignKey("NotifieeId")] [ForeignKey("NotifieeId")]
[InverseProperty("NotificationNotifiees")] [InverseProperty(nameof(User.NotificationNotifiees))]
public virtual User Notifiee { get; set; } = null!; public virtual User Notifiee { get; set; } = null!;
[ForeignKey("NotifierId")] [ForeignKey("NotifierId")]
[InverseProperty("NotificationNotifiers")] [InverseProperty(nameof(User.NotificationNotifiers))]
public virtual User? Notifier { get; set; } public virtual User? Notifier { get; set; }
[ForeignKey("UserGroupInvitationId")] [ForeignKey("UserGroupInvitationId")]
[InverseProperty("Notifications")] [InverseProperty(nameof(Tables.UserGroupInvitation.Notifications))]
public virtual UserGroupInvitation? UserGroupInvitation { get; set; } public virtual UserGroupInvitation? UserGroupInvitation { get; set; }
[PgName("notification_type_enum")] [PgName("notification_type_enum")]

View file

@ -58,5 +58,5 @@ public class OauthApp {
[Column("redirectUris", TypeName = "character varying(512)[]")] [Column("redirectUris", TypeName = "character varying(512)[]")]
public List<string> RedirectUris { get; set; } = null!; public List<string> RedirectUris { get; set; } = null!;
[InverseProperty("App")] public virtual ICollection<OauthToken> OauthTokens { get; set; } = new List<OauthToken>(); [InverseProperty(nameof(OauthToken.App))] public virtual ICollection<OauthToken> OauthTokens { get; set; } = new List<OauthToken>();
} }

View file

@ -57,10 +57,10 @@ public class OauthToken {
public string RedirectUri { get; set; } = null!; public string RedirectUri { get; set; } = null!;
[ForeignKey("AppId")] [ForeignKey("AppId")]
[InverseProperty("OauthTokens")] [InverseProperty(nameof(OauthApp.OauthTokens))]
public virtual OauthApp App { get; set; } = null!; public virtual OauthApp App { get; set; } = null!;
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("OauthTokens")] [InverseProperty(nameof(Tables.User.OauthTokens))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
} }

View file

@ -75,16 +75,16 @@ public class Page {
[Column("isPublic")] public bool IsPublic { get; set; } [Column("isPublic")] public bool IsPublic { get; set; }
[ForeignKey("EyeCatchingImageId")] [ForeignKey("EyeCatchingImageId")]
[InverseProperty("Pages")] [InverseProperty(nameof(DriveFile.Pages))]
public virtual DriveFile? EyeCatchingImage { get; set; } public virtual DriveFile? EyeCatchingImage { get; set; }
[InverseProperty("Page")] public virtual ICollection<PageLike> PageLikes { get; set; } = new List<PageLike>(); [InverseProperty(nameof(PageLike.Page))] public virtual ICollection<PageLike> PageLikes { get; set; } = new List<PageLike>();
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("Pages")] [InverseProperty(nameof(Tables.User.Pages))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
[InverseProperty("PinnedPage")] public virtual UserProfile? UserProfile { get; set; } [InverseProperty(nameof(Tables.UserProfile.PinnedPage))] public virtual UserProfile? UserProfile { get; set; }
[PgName("page_visibility_enum")] [PgName("page_visibility_enum")]
public enum PageVisibility { public enum PageVisibility {

View file

@ -20,10 +20,10 @@ public class PageLike {
[Column("pageId")] [StringLength(32)] public string PageId { get; set; } = null!; [Column("pageId")] [StringLength(32)] public string PageId { get; set; } = null!;
[ForeignKey("PageId")] [ForeignKey("PageId")]
[InverseProperty("PageLikes")] [InverseProperty(nameof(Tables.Page.PageLikes))]
public virtual Page Page { get; set; } = null!; public virtual Page Page { get; set; } = null!;
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("PageLikes")] [InverseProperty(nameof(Tables.User.PageLikes))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
} }

View file

@ -20,6 +20,6 @@ public class PasswordResetRequest {
[Column("userId")] [StringLength(32)] public string UserId { get; set; } = null!; [Column("userId")] [StringLength(32)] public string UserId { get; set; } = null!;
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("PasswordResetRequests")] [InverseProperty(nameof(Tables.User.PasswordResetRequests))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
} }

View file

@ -38,7 +38,7 @@ public class Poll {
public string? UserHost { get; set; } public string? UserHost { get; set; }
[ForeignKey("NoteId")] [ForeignKey("NoteId")]
[InverseProperty("Poll")] [InverseProperty(nameof(Tables.Note.Poll))]
public virtual Note Note { get; set; } = null!; public virtual Note Note { get; set; } = null!;
/// <summary> /// <summary>

View file

@ -28,10 +28,10 @@ public class PollVote {
[Column("choice")] public int Choice { get; set; } [Column("choice")] public int Choice { get; set; }
[ForeignKey("NoteId")] [ForeignKey("NoteId")]
[InverseProperty("PollVotes")] [InverseProperty(nameof(Tables.Note.PollVotes))]
public virtual Note Note { get; set; } = null!; public virtual Note Note { get; set; } = null!;
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("PollVotes")] [InverseProperty(nameof(Tables.User.PollVotes))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
} }

View file

@ -22,6 +22,6 @@ public class PromoNote {
public string UserId { get; set; } = null!; public string UserId { get; set; } = null!;
[ForeignKey("NoteId")] [ForeignKey("NoteId")]
[InverseProperty("PromoNote")] [InverseProperty(nameof(Tables.Note.PromoNote))]
public virtual Note Note { get; set; } = null!; public virtual Note Note { get; set; } = null!;
} }

View file

@ -24,10 +24,10 @@ public class PromoRead {
[Column("noteId")] [StringLength(32)] public string NoteId { get; set; } = null!; [Column("noteId")] [StringLength(32)] public string NoteId { get; set; } = null!;
[ForeignKey("NoteId")] [ForeignKey("NoteId")]
[InverseProperty("PromoReads")] [InverseProperty(nameof(Tables.Note.PromoReads))]
public virtual Note Note { get; set; } = null!; public virtual Note Note { get; set; } = null!;
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("PromoReads")] [InverseProperty(nameof(Tables.User.PromoReads))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
} }

View file

@ -52,6 +52,6 @@ public class RegistryItem {
public string? Value { get; set; } public string? Value { get; set; }
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("RegistryItems")] [InverseProperty(nameof(Tables.User.RegistryItems))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
} }

View file

@ -36,10 +36,10 @@ public class RenoteMuting {
public string MuterId { get; set; } = null!; public string MuterId { get; set; } = null!;
[ForeignKey("MuteeId")] [ForeignKey("MuteeId")]
[InverseProperty("RenoteMutingMutees")] [InverseProperty(nameof(User.RenoteMutingMutees))]
public virtual User Mutee { get; set; } = null!; public virtual User Mutee { get; set; } = null!;
[ForeignKey("MuterId")] [ForeignKey("MuterId")]
[InverseProperty("RenoteMutingMuters")] [InverseProperty(nameof(User.RenoteMutingMuters))]
public virtual User Muter { get; set; } = null!; public virtual User Muter { get; set; } = null!;
} }

View file

@ -34,6 +34,6 @@ public class Session {
public bool Active { get; set; } public bool Active { get; set; }
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("Sessions")] [InverseProperty(nameof(Tables.User.Sessions))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
} }

View file

@ -28,6 +28,6 @@ public class Signin {
[Column("success")] public bool Success { get; set; } [Column("success")] public bool Success { get; set; }
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("Signins")] [InverseProperty(nameof(Tables.User.Signins))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
} }

View file

@ -29,6 +29,6 @@ public class SwSubscription {
[Column("sendReadMessage")] public bool SendReadMessage { get; set; } [Column("sendReadMessage")] public bool SendReadMessage { get; set; }
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("SwSubscriptions")] [InverseProperty(nameof(Tables.User.SwSubscriptions))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
} }

View file

@ -1,5 +1,7 @@
using System.ComponentModel.DataAnnotations; using System.Collections;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using EntityFrameworkCore.Projectables;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
namespace Iceshrimp.Backend.Core.Database.Tables; namespace Iceshrimp.Backend.Core.Database.Tables;
@ -258,169 +260,181 @@ public class User {
[StringLength(128)] [StringLength(128)]
public string? BannerBlurhash { get; set; } public string? BannerBlurhash { get; set; }
[InverseProperty("Assignee")] [InverseProperty(nameof(AbuseUserReport.Assignee))]
public virtual ICollection<AbuseUserReport> AbuseUserReportAssignees { get; set; } = new List<AbuseUserReport>(); public virtual ICollection<AbuseUserReport> AbuseUserReportAssignees { get; set; } = new List<AbuseUserReport>();
[InverseProperty("Reporter")] [InverseProperty(nameof(AbuseUserReport.Reporter))]
public virtual ICollection<AbuseUserReport> AbuseUserReportReporters { get; set; } = new List<AbuseUserReport>(); public virtual ICollection<AbuseUserReport> AbuseUserReportReporters { get; set; } = new List<AbuseUserReport>();
[InverseProperty("TargetUser")] [InverseProperty(nameof(AbuseUserReport.TargetUser))]
public virtual ICollection<AbuseUserReport> AbuseUserReportTargetUsers { get; set; } = new List<AbuseUserReport>(); public virtual ICollection<AbuseUserReport> AbuseUserReportTargetUsers { get; set; } = new List<AbuseUserReport>();
[InverseProperty("User")] [InverseProperty(nameof(AccessToken.User))]
public virtual ICollection<AccessToken> AccessTokens { get; set; } = new List<AccessToken>(); public virtual ICollection<AccessToken> AccessTokens { get; set; } = new List<AccessToken>();
[InverseProperty("User")] [InverseProperty(nameof(AnnouncementRead.User))]
public virtual ICollection<AnnouncementRead> AnnouncementReads { get; set; } = new List<AnnouncementRead>(); public virtual ICollection<AnnouncementRead> AnnouncementReads { get; set; } = new List<AnnouncementRead>();
[InverseProperty("User")] public virtual ICollection<Antenna> Antennas { get; set; } = new List<Antenna>(); [InverseProperty(nameof(Antenna.User))] public virtual ICollection<Antenna> Antennas { get; set; } = new List<Antenna>();
[InverseProperty("User")] public virtual ICollection<App> Apps { get; set; } = new List<App>(); [InverseProperty(nameof(App.User))] public virtual ICollection<App> Apps { get; set; } = new List<App>();
[InverseProperty("User")] [InverseProperty(nameof(AttestationChallenge.User))]
public virtual ICollection<AttestationChallenge> AttestationChallenges { get; set; } = public virtual ICollection<AttestationChallenge> AttestationChallenges { get; set; } =
new List<AttestationChallenge>(); new List<AttestationChallenge>();
[InverseProperty("User")] [InverseProperty(nameof(AuthSession.User))]
public virtual ICollection<AuthSession> AuthSessions { get; set; } = new List<AuthSession>(); public virtual ICollection<AuthSession> AuthSessions { get; set; } = new List<AuthSession>();
[ForeignKey("AvatarId")] [ForeignKey("AvatarId")]
[InverseProperty("UserAvatar")] [InverseProperty(nameof(DriveFile.UserAvatar))]
public virtual DriveFile? Avatar { get; set; } public virtual DriveFile? Avatar { get; set; }
[ForeignKey("BannerId")] [ForeignKey("BannerId")]
[InverseProperty("UserBanner")] [InverseProperty(nameof(DriveFile.UserBanner))]
public virtual DriveFile? Banner { get; set; } public virtual DriveFile? Banner { get; set; }
[InverseProperty("Blockee")] [InverseProperty(nameof(Blocking.Blockee))]
public virtual ICollection<Blocking> BlockingBlockees { get; set; } = new List<Blocking>(); public virtual ICollection<Blocking> BlockingBlockees { get; set; } = new List<Blocking>();
[InverseProperty("Blocker")] [InverseProperty(nameof(Blocking.Blocker))]
public virtual ICollection<Blocking> BlockingBlockers { get; set; } = new List<Blocking>(); public virtual ICollection<Blocking> BlockingBlockers { get; set; } = new List<Blocking>();
[InverseProperty("Follower")] [InverseProperty(nameof(ChannelFollowing.Follower))]
public virtual ICollection<ChannelFollowing> ChannelFollowings { get; set; } = new List<ChannelFollowing>(); public virtual ICollection<ChannelFollowing> ChannelFollowings { get; set; } = new List<ChannelFollowing>();
[InverseProperty("User")] public virtual ICollection<Channel> Channels { get; set; } = new List<Channel>(); [InverseProperty(nameof(Channel.User))] public virtual ICollection<Channel> Channels { get; set; } = new List<Channel>();
[InverseProperty("User")] public virtual ICollection<Clip> Clips { get; set; } = new List<Clip>(); [InverseProperty(nameof(Clip.User))] public virtual ICollection<Clip> Clips { get; set; } = new List<Clip>();
[InverseProperty("User")] public virtual ICollection<DriveFile> DriveFiles { get; set; } = new List<DriveFile>(); [InverseProperty(nameof(DriveFile.User))] public virtual ICollection<DriveFile> DriveFiles { get; set; } = new List<DriveFile>();
[InverseProperty("User")] [InverseProperty(nameof(DriveFolder.User))]
public virtual ICollection<DriveFolder> DriveFolders { get; set; } = new List<DriveFolder>(); public virtual ICollection<DriveFolder> DriveFolders { get; set; } = new List<DriveFolder>();
[InverseProperty("Followee")] [InverseProperty(nameof(FollowRequest.Followee))]
public virtual ICollection<FollowRequest> FollowRequestFollowees { get; set; } = new List<FollowRequest>(); public virtual ICollection<FollowRequest> IncomingFollowRequests { get; set; } = new List<FollowRequest>();
[InverseProperty("Follower")] [InverseProperty(nameof(FollowRequest.Follower))]
public virtual ICollection<FollowRequest> FollowRequestFollowers { get; set; } = new List<FollowRequest>(); public virtual ICollection<FollowRequest> OutgoingFollowRequests { get; set; } = new List<FollowRequest>();
[InverseProperty("Followee")] [InverseProperty(nameof(Tables.Following.Followee))]
public virtual ICollection<Following> FollowingFollowees { get; set; } = new List<Following>(); public virtual ICollection<Following> IncomingFollowRelationships { get; set; } = new List<Following>();
[InverseProperty("Follower")] [InverseProperty(nameof(Tables.Following.Follower))]
public virtual ICollection<Following> FollowingFollowers { get; set; } = new List<Following>(); public virtual ICollection<Following> OutgoingFollowRelationships { get; set; } = new List<Following>();
[InverseProperty("User")] [Projectable]
public virtual IEnumerable<User> Followers => IncomingFollowRelationships.Select(p => p.Follower);
[Projectable]
public virtual IEnumerable<User> Following => OutgoingFollowRelationships.Select(p => p.Followee);
[Projectable]
public bool IsFollowedBy(User user) => Followers.Contains(user);
[Projectable]
public bool IsFollowing(User user) => Following.Contains(user);
[InverseProperty(nameof(GalleryLike.User))]
public virtual ICollection<GalleryLike> GalleryLikes { get; set; } = new List<GalleryLike>(); public virtual ICollection<GalleryLike> GalleryLikes { get; set; } = new List<GalleryLike>();
[InverseProperty("User")] [InverseProperty(nameof(GalleryPost.User))]
public virtual ICollection<GalleryPost> GalleryPosts { get; set; } = new List<GalleryPost>(); public virtual ICollection<GalleryPost> GalleryPosts { get; set; } = new List<GalleryPost>();
[InverseProperty("User")] public virtual HtmlUserCacheEntry? HtmlUserCacheEntry { get; set; } [InverseProperty(nameof(Tables.HtmlUserCacheEntry.User))] public virtual HtmlUserCacheEntry? HtmlUserCacheEntry { get; set; }
[InverseProperty("Recipient")] [InverseProperty(nameof(MessagingMessage.Recipient))]
public virtual ICollection<MessagingMessage> MessagingMessageRecipients { get; set; } = public virtual ICollection<MessagingMessage> MessagingMessageRecipients { get; set; } =
new List<MessagingMessage>(); new List<MessagingMessage>();
[InverseProperty("User")] [InverseProperty(nameof(MessagingMessage.User))]
public virtual ICollection<MessagingMessage> MessagingMessageUsers { get; set; } = new List<MessagingMessage>(); public virtual ICollection<MessagingMessage> MessagingMessageUsers { get; set; } = new List<MessagingMessage>();
[InverseProperty("User")] [InverseProperty(nameof(ModerationLog.User))]
public virtual ICollection<ModerationLog> ModerationLogs { get; set; } = new List<ModerationLog>(); public virtual ICollection<ModerationLog> ModerationLogs { get; set; } = new List<ModerationLog>();
[InverseProperty("Mutee")] public virtual ICollection<Muting> MutingMutees { get; set; } = new List<Muting>(); [InverseProperty(nameof(Muting.Mutee))] public virtual ICollection<Muting> MutingMutees { get; set; } = new List<Muting>();
[InverseProperty("Muter")] public virtual ICollection<Muting> MutingMuters { get; set; } = new List<Muting>(); [InverseProperty(nameof(Muting.Muter))] public virtual ICollection<Muting> MutingMuters { get; set; } = new List<Muting>();
[InverseProperty("User")] [InverseProperty(nameof(NoteFavorite.User))]
public virtual ICollection<NoteFavorite> NoteFavorites { get; set; } = new List<NoteFavorite>(); public virtual ICollection<NoteFavorite> NoteFavorites { get; set; } = new List<NoteFavorite>();
[InverseProperty("User")] [InverseProperty(nameof(NoteReaction.User))]
public virtual ICollection<NoteReaction> NoteReactions { get; set; } = new List<NoteReaction>(); public virtual ICollection<NoteReaction> NoteReactions { get; set; } = new List<NoteReaction>();
[InverseProperty("User")] [InverseProperty(nameof(NoteThreadMuting.User))]
public virtual ICollection<NoteThreadMuting> NoteThreadMutings { get; set; } = new List<NoteThreadMuting>(); public virtual ICollection<NoteThreadMuting> NoteThreadMutings { get; set; } = new List<NoteThreadMuting>();
[InverseProperty("User")] public virtual ICollection<NoteUnread> NoteUnreads { get; set; } = new List<NoteUnread>(); [InverseProperty(nameof(NoteUnread.User))] public virtual ICollection<NoteUnread> NoteUnreads { get; set; } = new List<NoteUnread>();
[InverseProperty("User")] [InverseProperty(nameof(NoteWatching.User))]
public virtual ICollection<NoteWatching> NoteWatchings { get; set; } = new List<NoteWatching>(); public virtual ICollection<NoteWatching> NoteWatchings { get; set; } = new List<NoteWatching>();
[InverseProperty("User")] public virtual ICollection<Note> Notes { get; set; } = new List<Note>(); [InverseProperty(nameof(Note.User))] public virtual ICollection<Note> Notes { get; set; } = new List<Note>();
[InverseProperty("Notifiee")] [InverseProperty(nameof(Notification.Notifiee))]
public virtual ICollection<Notification> NotificationNotifiees { get; set; } = new List<Notification>(); public virtual ICollection<Notification> NotificationNotifiees { get; set; } = new List<Notification>();
[InverseProperty("Notifier")] [InverseProperty(nameof(Notification.Notifier))]
public virtual ICollection<Notification> NotificationNotifiers { get; set; } = new List<Notification>(); public virtual ICollection<Notification> NotificationNotifiers { get; set; } = new List<Notification>();
[InverseProperty("User")] public virtual ICollection<OauthToken> OauthTokens { get; set; } = new List<OauthToken>(); [InverseProperty(nameof(OauthToken.User))] public virtual ICollection<OauthToken> OauthTokens { get; set; } = new List<OauthToken>();
[InverseProperty("User")] public virtual ICollection<PageLike> PageLikes { get; set; } = new List<PageLike>(); [InverseProperty(nameof(PageLike.User))] public virtual ICollection<PageLike> PageLikes { get; set; } = new List<PageLike>();
[InverseProperty("User")] public virtual ICollection<Page> Pages { get; set; } = new List<Page>(); [InverseProperty(nameof(Page.User))] public virtual ICollection<Page> Pages { get; set; } = new List<Page>();
[InverseProperty("User")] [InverseProperty(nameof(PasswordResetRequest.User))]
public virtual ICollection<PasswordResetRequest> PasswordResetRequests { get; set; } = public virtual ICollection<PasswordResetRequest> PasswordResetRequests { get; set; } =
new List<PasswordResetRequest>(); new List<PasswordResetRequest>();
[InverseProperty("User")] public virtual ICollection<PollVote> PollVotes { get; set; } = new List<PollVote>(); [InverseProperty(nameof(PollVote.User))] public virtual ICollection<PollVote> PollVotes { get; set; } = new List<PollVote>();
[InverseProperty("User")] public virtual ICollection<PromoRead> PromoReads { get; set; } = new List<PromoRead>(); [InverseProperty(nameof(PromoRead.User))] public virtual ICollection<PromoRead> PromoReads { get; set; } = new List<PromoRead>();
[InverseProperty("User")] [InverseProperty(nameof(RegistryItem.User))]
public virtual ICollection<RegistryItem> RegistryItems { get; set; } = new List<RegistryItem>(); public virtual ICollection<RegistryItem> RegistryItems { get; set; } = new List<RegistryItem>();
[InverseProperty("Mutee")] [InverseProperty(nameof(RenoteMuting.Mutee))]
public virtual ICollection<RenoteMuting> RenoteMutingMutees { get; set; } = new List<RenoteMuting>(); public virtual ICollection<RenoteMuting> RenoteMutingMutees { get; set; } = new List<RenoteMuting>();
[InverseProperty("Muter")] [InverseProperty(nameof(RenoteMuting.Muter))]
public virtual ICollection<RenoteMuting> RenoteMutingMuters { get; set; } = new List<RenoteMuting>(); public virtual ICollection<RenoteMuting> RenoteMutingMuters { get; set; } = new List<RenoteMuting>();
[InverseProperty("User")] public virtual ICollection<Session> Sessions { get; set; } = new List<Session>(); [InverseProperty(nameof(Session.User))] public virtual ICollection<Session> Sessions { get; set; } = new List<Session>();
[InverseProperty("User")] public virtual ICollection<Signin> Signins { get; set; } = new List<Signin>(); [InverseProperty(nameof(Signin.User))] public virtual ICollection<Signin> Signins { get; set; } = new List<Signin>();
[InverseProperty("User")] [InverseProperty(nameof(SwSubscription.User))]
public virtual ICollection<SwSubscription> SwSubscriptions { get; set; } = new List<SwSubscription>(); public virtual ICollection<SwSubscription> SwSubscriptions { get; set; } = new List<SwSubscription>();
[InverseProperty("User")] [InverseProperty(nameof(UserGroupInvitation.User))]
public virtual ICollection<UserGroupInvitation> UserGroupInvitations { get; set; } = public virtual ICollection<UserGroupInvitation> UserGroupInvitations { get; set; } =
new List<UserGroupInvitation>(); new List<UserGroupInvitation>();
[InverseProperty("User")] [InverseProperty(nameof(UserGroupMember.User))]
public virtual ICollection<UserGroupMember> UserGroupMemberships { get; set; } = new List<UserGroupMember>(); public virtual ICollection<UserGroupMember> UserGroupMemberships { get; set; } = new List<UserGroupMember>();
[InverseProperty("User")] public virtual ICollection<UserGroup> UserGroups { get; set; } = new List<UserGroup>(); [InverseProperty(nameof(UserGroup.User))] public virtual ICollection<UserGroup> UserGroups { get; set; } = new List<UserGroup>();
[InverseProperty("User")] public virtual UserKeypair? UserKeypair { get; set; } [InverseProperty(nameof(Tables.UserKeypair.User))] public virtual UserKeypair? UserKeypair { get; set; }
[InverseProperty("User")] [InverseProperty(nameof(UserListMember.User))]
public virtual ICollection<UserListMember> UserListMembers { get; set; } = new List<UserListMember>(); public virtual ICollection<UserListMember> UserListMembers { get; set; } = new List<UserListMember>();
[InverseProperty("User")] public virtual ICollection<UserList> UserLists { get; set; } = new List<UserList>(); [InverseProperty(nameof(UserList.User))] public virtual ICollection<UserList> UserLists { get; set; } = new List<UserList>();
[InverseProperty("User")] [InverseProperty(nameof(UserNotePin.User))]
public virtual ICollection<UserNotePin> UserNotePins { get; set; } = new List<UserNotePin>(); public virtual ICollection<UserNotePin> UserNotePins { get; set; } = new List<UserNotePin>();
[InverseProperty("User")] public virtual UserProfile? UserProfile { get; set; } [InverseProperty(nameof(Tables.UserProfile.User))] public virtual UserProfile? UserProfile { get; set; }
[InverseProperty("User")] public virtual UserPublickey? UserPublickey { get; set; } [InverseProperty(nameof(Tables.UserPublickey.User))] public virtual UserPublickey? UserPublickey { get; set; }
[InverseProperty("User")] [InverseProperty(nameof(UserSecurityKey.User))]
public virtual ICollection<UserSecurityKey> UserSecurityKeys { get; set; } = new List<UserSecurityKey>(); public virtual ICollection<UserSecurityKey> UserSecurityKeys { get; set; } = new List<UserSecurityKey>();
[InverseProperty("User")] public virtual ICollection<Webhook> Webhooks { get; set; } = new List<Webhook>(); [InverseProperty(nameof(Webhook.User))] public virtual ICollection<Webhook> Webhooks { get; set; } = new List<Webhook>();
} }

View file

@ -30,17 +30,17 @@ public class UserGroup {
[Column("isPrivate")] public bool IsPrivate { get; set; } [Column("isPrivate")] public bool IsPrivate { get; set; }
[InverseProperty("Group")] [InverseProperty(nameof(MessagingMessage.Group))]
public virtual ICollection<MessagingMessage> MessagingMessages { get; set; } = new List<MessagingMessage>(); public virtual ICollection<MessagingMessage> MessagingMessages { get; set; } = new List<MessagingMessage>();
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("UserGroups")] [InverseProperty(nameof(Tables.User.UserGroups))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
[InverseProperty("UserGroup")] [InverseProperty(nameof(UserGroupInvitation.UserGroup))]
public virtual ICollection<UserGroupInvitation> UserGroupInvitations { get; set; } = public virtual ICollection<UserGroupInvitation> UserGroupInvitations { get; set; } =
new List<UserGroupInvitation>(); new List<UserGroupInvitation>();
[InverseProperty("UserGroup")] [InverseProperty(nameof(UserGroupMember.UserGroup))]
public virtual ICollection<UserGroupMember> UserGroupMembers { get; set; } = new List<UserGroupMember>(); public virtual ICollection<UserGroupMember> UserGroupMembers { get; set; } = new List<UserGroupMember>();
} }

View file

@ -34,14 +34,14 @@ public class UserGroupInvitation {
[StringLength(32)] [StringLength(32)]
public string UserGroupId { get; set; } = null!; public string UserGroupId { get; set; } = null!;
[InverseProperty("UserGroupInvitation")] [InverseProperty(nameof(Notification.UserGroupInvitation))]
public virtual ICollection<Notification> Notifications { get; set; } = new List<Notification>(); public virtual ICollection<Notification> Notifications { get; set; } = new List<Notification>();
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("UserGroupInvitations")] [InverseProperty(nameof(Tables.User.UserGroupInvitations))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
[ForeignKey("UserGroupId")] [ForeignKey("UserGroupId")]
[InverseProperty("UserGroupInvitations")] [InverseProperty(nameof(Tables.UserGroup.UserGroupInvitations))]
public virtual UserGroup UserGroup { get; set; } = null!; public virtual UserGroup UserGroup { get; set; } = null!;
} }

View file

@ -34,14 +34,14 @@ public class UserGroupMember {
[StringLength(32)] [StringLength(32)]
public string UserGroupId { get; set; } = null!; public string UserGroupId { get; set; } = null!;
[InverseProperty("UserGroupMember")] [InverseProperty(nameof(Antenna.UserGroupMember))]
public virtual ICollection<Antenna> Antennas { get; set; } = new List<Antenna>(); public virtual ICollection<Antenna> Antennas { get; set; } = new List<Antenna>();
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("UserGroupMemberships")] [InverseProperty(nameof(Tables.User.UserGroupMemberships))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
[ForeignKey("UserGroupId")] [ForeignKey("UserGroupId")]
[InverseProperty("UserGroupMembers")] [InverseProperty(nameof(Tables.UserGroup.UserGroupMembers))]
public virtual UserGroup UserGroup { get; set; } = null!; public virtual UserGroup UserGroup { get; set; } = null!;
} }

View file

@ -19,6 +19,6 @@ public class UserKeypair {
public string PrivateKey { get; set; } = null!; public string PrivateKey { get; set; } = null!;
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("UserKeypair")] [InverseProperty(nameof(Tables.User.UserKeypair))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
} }

View file

@ -38,12 +38,12 @@ public class UserList {
[Column("hideFromHomeTl")] [Column("hideFromHomeTl")]
public bool HideFromHomeTl { get; set; } public bool HideFromHomeTl { get; set; }
[InverseProperty("UserList")] public virtual ICollection<Antenna> Antennas { get; set; } = new List<Antenna>(); [InverseProperty(nameof(Antenna.UserList))] public virtual ICollection<Antenna> Antennas { get; set; } = new List<Antenna>();
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("UserLists")] [InverseProperty(nameof(Tables.User.UserLists))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
[InverseProperty("UserList")] [InverseProperty(nameof(UserListMember.UserList))]
public virtual ICollection<UserListMember> UserListMembers { get; set; } = new List<UserListMember>(); public virtual ICollection<UserListMember> UserListMembers { get; set; } = new List<UserListMember>();
} }

View file

@ -35,10 +35,10 @@ public class UserListMember {
public string UserListId { get; set; } = null!; public string UserListId { get; set; } = null!;
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("UserListMembers")] [InverseProperty(nameof(Tables.User.UserListMembers))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
[ForeignKey("UserListId")] [ForeignKey("UserListId")]
[InverseProperty("UserListMembers")] [InverseProperty(nameof(Tables.UserList.UserListMembers))]
public virtual UserList UserList { get; set; } = null!; public virtual UserList UserList { get; set; } = null!;
} }

View file

@ -24,10 +24,10 @@ public class UserNotePin {
[Column("noteId")] [StringLength(32)] public string NoteId { get; set; } = null!; [Column("noteId")] [StringLength(32)] public string NoteId { get; set; } = null!;
[ForeignKey("NoteId")] [ForeignKey("NoteId")]
[InverseProperty("UserNotePins")] [InverseProperty(nameof(Tables.Note.UserNotePins))]
public virtual Note Note { get; set; } = null!; public virtual Note Note { get; set; } = null!;
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("UserNotePins")] [InverseProperty(nameof(Tables.User.UserNotePins))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
} }

View file

@ -155,11 +155,11 @@ public class UserProfile {
public string Mentions { get; set; } = null!; public string Mentions { get; set; } = null!;
[ForeignKey("PinnedPageId")] [ForeignKey("PinnedPageId")]
[InverseProperty("UserProfile")] [InverseProperty(nameof(Page.UserProfile))]
public virtual Page? PinnedPage { get; set; } public virtual Page? PinnedPage { get; set; }
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("UserProfile")] [InverseProperty(nameof(Tables.User.UserProfile))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
[PgName("user_profile_ffvisibility_enum")] [PgName("user_profile_ffvisibility_enum")]

View file

@ -19,6 +19,6 @@ public class UserPublickey {
public string KeyPem { get; set; } = null!; public string KeyPem { get; set; } = null!;
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("UserPublickey")] [InverseProperty(nameof(Tables.User.UserPublickey))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
} }

View file

@ -37,6 +37,6 @@ public class UserSecurityKey {
public string Name { get; set; } = null!; public string Name { get; set; } = null!;
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("UserSecurityKeys")] [InverseProperty(nameof(Tables.User.UserSecurityKeys))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
} }

View file

@ -50,6 +50,6 @@ public class Webhook {
[Column("latestStatus")] public int? LatestStatus { get; set; } [Column("latestStatus")] public int? LatestStatus { get; set; }
[ForeignKey("UserId")] [ForeignKey("UserId")]
[InverseProperty("Webhooks")] [InverseProperty(nameof(Tables.User.Webhooks))]
public virtual User User { get; set; } = null!; public virtual User User { get; set; } = null!;
} }

View file

@ -1,16 +1,7 @@
using Iceshrimp.Backend.Controllers.Mastodon.Renderers;
using Iceshrimp.Backend.Controllers.Mastodon.Schemas.Entities;
using Iceshrimp.Backend.Core.Database.Tables;
namespace Iceshrimp.Backend.Core.Extensions; namespace Iceshrimp.Backend.Core.Extensions;
public static class EnumerableExtensions { public static class EnumerableExtensions {
public static async Task<IEnumerable<T>> AwaitAllAsync<T>(this IEnumerable<Task<T>> tasks) { public static async Task<IEnumerable<T>> AwaitAllAsync<T>(this IEnumerable<Task<T>> tasks) {
return await Task.WhenAll(tasks); return await Task.WhenAll(tasks);
} }
public static async Task<IEnumerable<Status>> RenderAllForMastodonAsync(
this IEnumerable<Note> notes, NoteRenderer renderer) {
return await notes.Select(async p => await renderer.RenderAsync(p)).AwaitAllAsync();
}
} }

View file

@ -1,9 +1,11 @@
using Iceshrimp.Backend.Controllers.Mastodon.Renderers;
using Iceshrimp.Backend.Controllers.Mastodon.Schemas.Entities;
using Iceshrimp.Backend.Core.Database.Tables; using Iceshrimp.Backend.Core.Database.Tables;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
namespace Iceshrimp.Backend.Core.Helpers; namespace Iceshrimp.Backend.Core.Extensions;
public static class QueryHelpers { public static class NoteQueryableExtensions {
public static IQueryable<Note> WithIncludes(this IQueryable<Note> query) { public static IQueryable<Note> WithIncludes(this IQueryable<Note> query) {
return query.Include(p => p.User) return query.Include(p => p.User)
.Include(p => p.Renote) .Include(p => p.Renote)
@ -16,11 +18,17 @@ public static class QueryHelpers {
return query.Where(note => note.Visibility == visibility); return query.Where(note => note.Visibility == visibility);
} }
public static IQueryable<Note> IsFollowedBy(this IQueryable<Note> query, User user) { public static IQueryable<Note> FilterByFollowingAndOwn(this IQueryable<Note> query, User user) {
return query.Where(note => note.User.FollowingFollowees.Any(following => following.Follower == user)); return query.Where(note => note.User == user || note.User.IsFollowedBy(user));
} }
public static IQueryable<Note> OrderByIdDesc(this IQueryable<Note> query) { public static IQueryable<Note> OrderByIdDesc(this IQueryable<Note> query) {
return query.OrderByDescending(note => note.Id); return query.OrderByDescending(note => note.Id);
} }
public static async Task<IEnumerable<Status>> RenderAllForMastodonAsync(
this IQueryable<Note> notes, NoteRenderer renderer) {
var list = await notes.ToListAsync();
return await list.Select(renderer.RenderAsync).AwaitAllAsync();
}
} }

View file

@ -18,6 +18,7 @@
<PackageReference Include="Asp.Versioning.Http" Version="8.0.0"/> <PackageReference Include="Asp.Versioning.Http" Version="8.0.0"/>
<PackageReference Include="cuid.net" Version="5.0.2"/> <PackageReference Include="cuid.net" Version="5.0.2"/>
<PackageReference Include="dotNetRdf.Core" Version="3.2.1-dev"/> <PackageReference Include="dotNetRdf.Core" Version="3.2.1-dev"/>
<PackageReference Include="EntityFrameworkCore.Projectables" Version="3.0.4" />
<PackageReference Include="Isopoh.Cryptography.Argon2" Version="2.0.0"/> <PackageReference Include="Isopoh.Cryptography.Argon2" Version="2.0.0"/>
<PackageReference Include="Microsoft.AspNetCore.DataProtection.EntityFrameworkCore" Version="8.0.1"/> <PackageReference Include="Microsoft.AspNetCore.DataProtection.EntityFrameworkCore" Version="8.0.1"/>
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.0"/> <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.0"/>