From 7594a16e38304739487b053405153379faee6e58 Mon Sep 17 00:00:00 2001 From: crupest Date: Thu, 7 Jan 2021 16:23:20 +0800 Subject: 史诗级重构! MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BackEnd/Timeline/Services/TimelinePostService.cs | 221 +++++++---------------- 1 file changed, 66 insertions(+), 155 deletions(-) (limited to 'BackEnd/Timeline/Services/TimelinePostService.cs') diff --git a/BackEnd/Timeline/Services/TimelinePostService.cs b/BackEnd/Timeline/Services/TimelinePostService.cs index 35513a36..9f0fd550 100644 --- a/BackEnd/Timeline/Services/TimelinePostService.cs +++ b/BackEnd/Timeline/Services/TimelinePostService.cs @@ -29,103 +29,74 @@ namespace Timeline.Services /// /// Get all the posts in the timeline. /// - /// The name of the timeline. + /// The id of the timeline. /// The time that posts have been modified since. /// Whether include deleted posts. /// A list of all posts. - /// Thrown when is null. - /// Throw when is of bad format. - /// - /// Thrown when timeline with name does not exist. - /// If it is a personal timeline, then inner exception is . - /// - Task> GetPosts(string timelineName, DateTime? modifiedSince = null, bool includeDeleted = false); + /// Thrown when timeline does not exist. + Task> GetPosts(long timelineId, DateTime? modifiedSince = null, bool includeDeleted = false); /// /// Get the etag of data of a post. /// - /// The name of the timeline of the post. + /// The id of the timeline of the post. /// The id of the post. /// The etag of the data. - /// Thrown when is null. - /// Throw when is of bad format. - /// - /// Thrown when timeline with name does not exist. - /// If it is a personal timeline, then inner exception is . - /// + /// Thrown when timeline does not exist. /// Thrown when post of does not exist or has been deleted. /// Thrown when post has no data. - /// - Task GetPostDataETag(string timelineName, long postId); + Task GetPostDataETag(long timelineId, long postId); /// /// Get the data of a post. /// - /// The name of the timeline of the post. + /// The id of the timeline of the post. /// The id of the post. /// The etag of the data. - /// Thrown when is null. - /// Throw when is of bad format. - /// - /// Thrown when timeline with name does not exist. - /// If it is a personal timeline, then inner exception is . - /// + /// Thrown when timeline does not exist. /// Thrown when post of does not exist or has been deleted. /// Thrown when post has no data. - /// - Task GetPostData(string timelineName, long postId); + /// + Task GetPostData(long timelineId, long postId); /// /// Create a new text post in timeline. /// - /// The name of the timeline to create post against. + /// The id of the timeline to create post against. /// The author's user id. /// The content text. /// The time of the post. If null, then current time is used. /// The info of the created post. - /// Thrown when or is null. - /// Throw when is of bad format. - /// - /// Thrown when timeline with name does not exist. - /// If it is a personal timeline, then inner exception is . - /// + /// Thrown when is null. + /// Thrown when timeline does not exist. /// Thrown if user of does not exist. - Task CreateTextPost(string timelineName, long authorId, string text, DateTime? time); + Task CreateTextPost(long timelineId, long authorId, string text, DateTime? time); /// /// Create a new image post in timeline. /// - /// The name of the timeline to create post against. + /// The id of the timeline to create post against. /// The author's user id. /// The image data. /// The time of the post. If null, then use current time. /// The info of the created post. - /// Thrown when or is null. - /// Throw when is of bad format. - /// - /// Thrown when timeline with name does not exist. - /// If it is a personal timeline, then inner exception is . - /// + /// Thrown when is null. + /// Thrown when timeline does not exist. /// Thrown if user of does not exist. /// Thrown if data is not a image. Validated by . - Task CreateImagePost(string timelineName, long authorId, byte[] imageData, DateTime? time); + Task CreateImagePost(long timelineId, long authorId, byte[] imageData, DateTime? time); /// /// Delete a post. /// - /// The name of the timeline to delete post against. + /// The id of the timeline to delete post against. /// The id of the post to delete. - /// Thrown when is null. - /// Throw when is of bad format. - /// - /// Thrown when timeline with name does not exist. - /// If it is a personal timeline, then inner exception is . - /// + /// Thrown when timeline does not exist. /// Thrown when the post with given id does not exist or is deleted already. /// - /// First use to check the permission. + /// First use to check the permission. /// - Task DeletePost(string timelineName, long postId); + Task DeletePost(long timelineId, long postId); /// /// Delete all posts of the given user. Used when delete a user. @@ -136,17 +107,12 @@ namespace Timeline.Services /// /// Verify whether a user has the permission to modify a post. /// - /// The name of the timeline. + /// The id of the timeline. /// The id of the post. /// The id of the user to check on. /// True if you want it to throw . Default false. /// True if can modify, false if can't modify. - /// Thrown when is null. - /// Throw when is of bad format. - /// - /// Thrown when timeline with name does not exist. - /// If it is a personal timeline, then inner exception is . - /// + /// Thrown when timeline does not exist. /// Thrown when the post with given id does not exist or is deleted already and is true. /// /// Unless is true, this method should return true if the post does not exist. @@ -155,7 +121,7 @@ namespace Timeline.Services /// It only checks whether he is the author of the post or the owner of the timeline. /// Return false when user with modifier id does not exist. /// - Task HasPostModifyPermission(string timelineName, long postId, long modifierId, bool throwOnPostNotExist = false); + Task HasPostModifyPermission(long timelineId, long postId, long modifierId, bool throwOnPostNotExist = false); } public class TimelinePostService : ITimelinePostService @@ -179,42 +145,18 @@ namespace Timeline.Services _clock = clock; } - private async Task MapTimelinePostFromEntity(TimelinePostEntity entity, string timelineName) + private async Task CheckTimelineExistence(long timelineId) { - UserInfo? author = entity.AuthorId.HasValue ? await _userService.GetUser(entity.AuthorId.Value) : null; - - ITimelinePostContent? content = null; - - if (entity.Content != null) - { - var type = entity.ContentType; - - content = type switch - { - TimelinePostContentTypes.Text => new TextTimelinePostContent(entity.Content), - TimelinePostContentTypes.Image => new ImageTimelinePostContent(entity.Content), - _ => throw new DatabaseCorruptedException(string.Format(CultureInfo.InvariantCulture, ExceptionDatabaseUnknownContentType, type)) - }; - } - - return new TimelinePostInfo( - id: entity.LocalId, - author: author, - content: content, - time: entity.Time, - lastUpdated: entity.LastUpdated, - timelineName: timelineName - ); + if (!await _basicTimelineService.CheckExistence(timelineId)) + throw new TimelineNotExistException(timelineId); } - public async Task> GetPosts(string timelineName, DateTime? modifiedSince = null, bool includeDeleted = false) + public async Task> GetPosts(long timelineId, DateTime? modifiedSince = null, bool includeDeleted = false) { - modifiedSince = modifiedSince?.MyToUtc(); + await CheckTimelineExistence(timelineId); - if (timelineName == null) - throw new ArgumentNullException(nameof(timelineName)); + modifiedSince = modifiedSince?.MyToUtc(); - var timelineId = await _basicTimelineService.GetTimelineIdByName(timelineName); IQueryable query = _database.TimelinePosts.Where(p => p.TimelineId == timelineId); if (!includeDeleted) @@ -229,30 +171,20 @@ namespace Timeline.Services query = query.OrderBy(p => p.Time); - var postEntities = await query.ToListAsync(); - - var posts = new List(); - foreach (var entity in postEntities) - { - posts.Add(await MapTimelinePostFromEntity(entity, timelineName)); - } - return posts; + return await query.Include(p => p.Author!.Permissions).ToListAsync(); } - public async Task GetPostDataETag(string timelineName, long postId) + public async Task GetPostDataETag(long timelineId, long postId) { - if (timelineName == null) - throw new ArgumentNullException(nameof(timelineName)); - - var timelineId = await _basicTimelineService.GetTimelineIdByName(timelineName); + await CheckTimelineExistence(timelineId); var postEntity = await _database.TimelinePosts.Where(p => p.TimelineId == timelineId && p.LocalId == postId).SingleOrDefaultAsync(); if (postEntity == null) - throw new TimelinePostNotExistException(timelineName, postId, false); + throw new TimelinePostNotExistException(timelineId, postId, false); if (postEntity.Content == null) - throw new TimelinePostNotExistException(timelineName, postId, true); + throw new TimelinePostNotExistException(timelineId, postId, true); if (postEntity.ContentType != TimelinePostContentTypes.Image) throw new TimelinePostNoDataException(ExceptionGetDataNonImagePost); @@ -262,19 +194,17 @@ namespace Timeline.Services return tag; } - public async Task GetPostData(string timelineName, long postId) + public async Task GetPostData(long timelineId, long postId) { - if (timelineName == null) - throw new ArgumentNullException(nameof(timelineName)); + await CheckTimelineExistence(timelineId); - var timelineId = await _basicTimelineService.GetTimelineIdByName(timelineName); var postEntity = await _database.TimelinePosts.Where(p => p.TimelineId == timelineId && p.LocalId == postId).SingleOrDefaultAsync(); if (postEntity == null) - throw new TimelinePostNotExistException(timelineName, postId, false); + throw new TimelinePostNotExistException(timelineId, postId, false); if (postEntity.Content == null) - throw new TimelinePostNotExistException(timelineName, postId, true); + throw new TimelinePostNotExistException(timelineId, postId, true); if (postEntity.ContentType != TimelinePostContentTypes.Image) throw new TimelinePostNoDataException(ExceptionGetDataNonImagePost); @@ -309,16 +239,15 @@ namespace Timeline.Services }; } - public async Task CreateTextPost(string timelineName, long authorId, string text, DateTime? time) + public async Task CreateTextPost(long timelineId, long authorId, string text, DateTime? time) { - time = time?.MyToUtc(); - - if (timelineName == null) - throw new ArgumentNullException(nameof(timelineName)); - if (text == null) + if (text is null) throw new ArgumentNullException(nameof(text)); - var timelineId = await _basicTimelineService.GetTimelineIdByName(timelineName); + await CheckTimelineExistence(timelineId); + + time = time?.MyToUtc(); + var timelineEntity = await _database.Timelines.Where(t => t.Id == timelineId).SingleAsync(); var author = await _userService.GetUser(authorId); @@ -341,27 +270,20 @@ namespace Timeline.Services _database.TimelinePosts.Add(postEntity); await _database.SaveChangesAsync(); + await _database.Entry(postEntity).Reference(p => p.Author).Query().Include(a => a.Permissions).LoadAsync(); - return new TimelinePostInfo( - id: postEntity.LocalId, - content: new TextTimelinePostContent(text), - time: finalTime, - author: author, - lastUpdated: currentTime, - timelineName: timelineName - ); + return postEntity; } - public async Task CreateImagePost(string timelineName, long authorId, byte[] data, DateTime? time) + public async Task CreateImagePost(long timelineId, long authorId, byte[] data, DateTime? time) { - time = time?.MyToUtc(); - - if (timelineName == null) - throw new ArgumentNullException(nameof(timelineName)); - if (data == null) + if (data is null) throw new ArgumentNullException(nameof(data)); - var timelineId = await _basicTimelineService.GetTimelineIdByName(timelineName); + await CheckTimelineExistence(timelineId); + + time = time?.MyToUtc(); + var timelineEntity = await _database.Timelines.Where(t => t.Id == timelineId).SingleAsync(); var author = await _userService.GetUser(authorId); @@ -391,30 +313,22 @@ namespace Timeline.Services _database.TimelinePosts.Add(postEntity); await _database.SaveChangesAsync(); - return new TimelinePostInfo( - id: postEntity.LocalId, - content: new ImageTimelinePostContent(tag), - time: finalTime, - author: author, - lastUpdated: currentTime, - timelineName: timelineName - ); + await _database.Entry(postEntity).Reference(p => p.Author).Query().Include(a => a.Permissions).LoadAsync(); + + return postEntity; } - public async Task DeletePost(string timelineName, long id) + public async Task DeletePost(long timelineId, long postId) { - if (timelineName == null) - throw new ArgumentNullException(nameof(timelineName)); - - var timelineId = await _basicTimelineService.GetTimelineIdByName(timelineName); + await CheckTimelineExistence(timelineId); - var post = await _database.TimelinePosts.Where(p => p.TimelineId == timelineId && p.LocalId == id).SingleOrDefaultAsync(); + var post = await _database.TimelinePosts.Where(p => p.TimelineId == timelineId && p.LocalId == postId).SingleOrDefaultAsync(); if (post == null) - throw new TimelinePostNotExistException(timelineName, id, false); + throw new TimelinePostNotExistException(timelineId, postId, false); if (post.Content == null) - throw new TimelinePostNotExistException(timelineName, id, true); + throw new TimelinePostNotExistException(timelineId, postId, true); string? dataTag = null; @@ -463,12 +377,9 @@ namespace Timeline.Services } } - public async Task HasPostModifyPermission(string timelineName, long postId, long modifierId, bool throwOnPostNotExist = false) + public async Task HasPostModifyPermission(long timelineId, long postId, long modifierId, bool throwOnPostNotExist = false) { - if (timelineName == null) - throw new ArgumentNullException(nameof(timelineName)); - - var timelineId = await _basicTimelineService.GetTimelineIdByName(timelineName); + await CheckTimelineExistence(timelineId); var timelineEntity = await _database.Timelines.Where(t => t.Id == timelineId).Select(t => new { t.OwnerId }).SingleAsync(); @@ -477,14 +388,14 @@ namespace Timeline.Services if (postEntity == null) { if (throwOnPostNotExist) - throw new TimelinePostNotExistException(timelineName, postId, false); + throw new TimelinePostNotExistException(timelineId, postId, false); else return true; } if (postEntity.Content == null && throwOnPostNotExist) { - throw new TimelinePostNotExistException(timelineName, postId, true); + throw new TimelinePostNotExistException(timelineId, postId, true); } return timelineEntity.OwnerId == modifierId || postEntity.AuthorId == modifierId; -- cgit v1.2.3