diff options
author | crupest <crupest@outlook.com> | 2020-12-18 19:26:50 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2020-12-18 19:26:50 +0800 |
commit | 53291d2c16047d3eb4c5eeb9a216c106cf47ead3 (patch) | |
tree | 5a437ebc7badc0ab3e8b84fa35b3604e66e94b8c | |
parent | 12e94f1ee5cd34d0dfc2db4f971d0de78fa84c06 (diff) | |
download | timeline-53291d2c16047d3eb4c5eeb9a216c106cf47ead3.tar.gz timeline-53291d2c16047d3eb4c5eeb9a216c106cf47ead3.tar.bz2 timeline-53291d2c16047d3eb4c5eeb9a216c106cf47ead3.zip |
feat: Implement bookmark service.
-rw-r--r-- | BackEnd/Timeline/Entities/DatabaseContext.cs | 1 | ||||
-rw-r--r-- | BackEnd/Timeline/Services/BookmarkTimelineService.cs | 127 |
2 files changed, 124 insertions, 4 deletions
diff --git a/BackEnd/Timeline/Entities/DatabaseContext.cs b/BackEnd/Timeline/Entities/DatabaseContext.cs index 4205c2cf..513cdc95 100644 --- a/BackEnd/Timeline/Entities/DatabaseContext.cs +++ b/BackEnd/Timeline/Entities/DatabaseContext.cs @@ -30,6 +30,7 @@ namespace Timeline.Entities public DbSet<TimelinePostEntity> TimelinePosts { get; set; } = default!;
public DbSet<TimelineMemberEntity> TimelineMembers { get; set; } = default!;
public DbSet<HighlightTimelineEntity> HighlightTimelines { get; set; } = default!;
+ public DbSet<BookmarkTimelineEntity> BookmarkTimelines { get; set; } = default!;
public DbSet<JwtTokenEntity> JwtToken { get; set; } = default!;
public DbSet<DataEntity> Data { get; set; } = default!;
diff --git a/BackEnd/Timeline/Services/BookmarkTimelineService.cs b/BackEnd/Timeline/Services/BookmarkTimelineService.cs index 7eb691b7..f65a1ff0 100644 --- a/BackEnd/Timeline/Services/BookmarkTimelineService.cs +++ b/BackEnd/Timeline/Services/BookmarkTimelineService.cs @@ -1,6 +1,9 @@ -using System;
+using Microsoft.EntityFrameworkCore;
+using System;
using System.Collections.Generic;
+using System.Linq;
using System.Threading.Tasks;
+using Timeline.Entities;
using Timeline.Models;
using Timeline.Services.Exceptions;
@@ -59,16 +62,132 @@ namespace Timeline.Services /// </summary>
/// <param name="userId">User id of bookmark owner.</param>
/// <param name="timelineName">Timeline name.</param>
- /// <param name="position">New position. Starts at 1.</param>
+ /// <param name="newPosition">New position. Starts at 1.</param>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="timelineName"/> is null.</exception>
/// <exception cref="ArgumentException">Thrown when <paramref name="timelineName"/> is not a valid name.</exception>
/// <exception cref="UserNotExistException">Thrown when user does not exist.</exception>
/// <exception cref="TimelineNotExistException">Thrown when timeline does not exist.</exception>
/// <exception cref="InvalidBookmarkException">Thrown when the timeline is not a bookmark.</exception>
- Task MoveBookmark(long userId, string timelineName, long position);
+ Task MoveBookmark(long userId, string timelineName, long newPosition);
}
- public class BookmarkTimelineService
+ public class BookmarkTimelineService : IBookmarkTimelineService
{
+ private readonly DatabaseContext _database;
+ private readonly IBasicUserService _userService;
+ private readonly ITimelineService _timelineService;
+
+ public BookmarkTimelineService(DatabaseContext database, IBasicUserService userService, ITimelineService timelineService)
+ {
+ _database = database;
+ _userService = userService;
+ _timelineService = timelineService;
+ }
+
+ public async Task AddBookmark(long userId, string timelineName)
+ {
+ if (timelineName is null)
+ throw new ArgumentNullException(nameof(timelineName));
+
+ if (!await _userService.CheckUserExistence(userId))
+ throw new UserNotExistException(userId);
+
+ var timelineId = await _timelineService.GetTimelineIdByName(timelineName);
+
+ _database.BookmarkTimelines.Add(new BookmarkTimelineEntity
+ {
+ TimelineId = timelineId,
+ UserId = userId,
+ Rank = (await _database.BookmarkTimelines.CountAsync(t => t.UserId == userId)) + 1
+ });
+
+ await _database.SaveChangesAsync();
+ }
+
+ public async Task<List<TimelineInfo>> GetBookmarks(long userId)
+ {
+ if (!await _userService.CheckUserExistence(userId))
+ throw new UserNotExistException(userId);
+
+ var entities = await _database.BookmarkTimelines.Where(t => t.UserId == userId).Select(t => new { t.TimelineId }).ToListAsync();
+
+ List<TimelineInfo> result = new();
+
+ foreach (var entity in entities)
+ {
+ result.Add(await _timelineService.GetTimelineById(entity.TimelineId));
+ }
+
+ return result;
+ }
+
+ public async Task MoveBookmark(long userId, string timelineName, long newPosition)
+ {
+ if (timelineName == null)
+ throw new ArgumentNullException(nameof(timelineName));
+
+ var timelineId = await _timelineService.GetTimelineIdByName(timelineName);
+
+ var entity = await _database.BookmarkTimelines.SingleOrDefaultAsync(t => t.TimelineId == timelineId && t.UserId == userId);
+
+ if (entity == null) throw new InvalidBookmarkException("You can't move a non-bookmark timeline.");
+
+ var oldPosition = entity.Rank;
+
+ if (newPosition < 1)
+ {
+ newPosition = 1;
+ }
+ else
+ {
+ var totalCount = await _database.HighlightTimelines.CountAsync();
+ if (newPosition > totalCount) newPosition = totalCount;
+ }
+
+ if (oldPosition == newPosition) return;
+
+ await using var transaction = await _database.Database.BeginTransactionAsync();
+
+ if (newPosition > oldPosition)
+ {
+ await _database.Database.ExecuteSqlRawAsync("UPDATE `bookmark_timelines` SET `rank` = `rank` - 1 WHERE `rank` BETWEEN {0} AND {1} AND `user` = {2}", oldPosition + 1, newPosition, userId);
+ await _database.Database.ExecuteSqlRawAsync("UPDATE `bookmark_timelines` SET `rank` = {0} WHERE `id` = {1}", newPosition, entity.Id);
+ }
+ else
+ {
+ await _database.Database.ExecuteSqlRawAsync("UPDATE `bookmark_timelines` SET `rank` = `rank` + 1 WHERE `rank` BETWEEN {0} AND {1} AND `user` = {2}", newPosition, oldPosition - 1, userId);
+ await _database.Database.ExecuteSqlRawAsync("UPDATE `bookmark_timelines` SET `rank` = {0} WHERE `id` = {1}", newPosition, entity.Id);
+ }
+
+ await transaction.CommitAsync();
+ }
+
+ public async Task<bool> RemoveBookmark(long userId, string timelineName)
+ {
+ if (timelineName is null)
+ throw new ArgumentNullException(nameof(timelineName));
+
+ if (!await _userService.CheckUserExistence(userId))
+ throw new UserNotExistException(userId);
+
+ var timelineId = await _timelineService.GetTimelineIdByName(timelineName);
+
+ var entity = await _database.BookmarkTimelines.SingleOrDefaultAsync(t => t.UserId == userId && t.TimelineId == timelineId);
+
+ if (entity == null) return false;
+
+ await using var transaction = await _database.Database.BeginTransactionAsync();
+
+ var rank = entity.Rank;
+
+ _database.BookmarkTimelines.Remove(entity);
+ await _database.SaveChangesAsync();
+
+ await _database.Database.ExecuteSqlRawAsync("UPDATE `bookmark_timelines` SET `rank` = `rank` - 1 WHERE `rank` > {0}", rank);
+
+ await transaction.CommitAsync();
+
+ return true;
+ }
}
}
|