Added endpoint and functionality for getting, retrieving and deleting bookmarks, and for adding and removing tags for a bookmark
This commit is contained in:
103
YABA.API/Controllers/BookmarksController.cs
Normal file
103
YABA.API/Controllers/BookmarksController.cs
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
using AutoMapper;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.Net;
|
||||||
|
using YABA.API.ViewModels;
|
||||||
|
using YABA.Common.DTOs.Bookmarks;
|
||||||
|
using YABA.Common.DTOs.Tags;
|
||||||
|
using YABA.Service.Interfaces;
|
||||||
|
|
||||||
|
namespace YABA.API.Controllers
|
||||||
|
{
|
||||||
|
[ApiVersion("1")]
|
||||||
|
[Authorize, Route("api/v{version:apiVersion}/[controller]")]
|
||||||
|
public class BookmarksController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly IBookmarkService _bookmarkService;
|
||||||
|
|
||||||
|
public BookmarksController(IBookmarkService bookmarkService)
|
||||||
|
{
|
||||||
|
_bookmarkService = bookmarkService;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[ProducesResponseType(typeof(GenericResponse<CreateBookmarkRequestDTO>), (int)HttpStatusCode.OK)]
|
||||||
|
[ProducesResponseType((int)HttpStatusCode.BadRequest)]
|
||||||
|
public async Task<IActionResult> Create(CreateBookmarkRequestDTO request)
|
||||||
|
{
|
||||||
|
var result = await _bookmarkService.CreateBookmark(request);
|
||||||
|
|
||||||
|
if(!result.IsSuccessful) return BadRequest();
|
||||||
|
|
||||||
|
return Ok(new GenericResponse<CreateBookmarkRequestDTO>(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("{id}/Tags")]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<GenericResponse<string>>),(int)HttpStatusCode.OK)]
|
||||||
|
[ProducesResponseType((int)HttpStatusCode.NotFound)]
|
||||||
|
public async Task<IActionResult> UpdateBookmarkTags(int id, IEnumerable<string> tags)
|
||||||
|
{
|
||||||
|
var result = await _bookmarkService.UpdateBookmarkTags(id, tags);
|
||||||
|
|
||||||
|
if (result.All(x => !x.IsSuccessful)) return NotFound();
|
||||||
|
|
||||||
|
return Ok(result.Select(x => new GenericResponse<string>(x)));
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[ProducesResponseType(typeof(GenericResponse<IEnumerable<BookmarkDTO>>), (int)HttpStatusCode.OK)]
|
||||||
|
public IActionResult GetAll()
|
||||||
|
{
|
||||||
|
var result = _bookmarkService.GetAll();
|
||||||
|
return Ok(new GenericResponse<IEnumerable<BookmarkDTO>>(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{id}")]
|
||||||
|
[ProducesResponseType(typeof(GenericResponse<BookmarkDTO>), (int)HttpStatusCode.OK)]
|
||||||
|
[ProducesResponseType((int)HttpStatusCode.NotFound)]
|
||||||
|
public async Task<IActionResult> Get(int id)
|
||||||
|
{
|
||||||
|
var result = await _bookmarkService.Get(id);
|
||||||
|
|
||||||
|
if (!result.IsSuccessful) return NotFound();
|
||||||
|
|
||||||
|
return Ok(new GenericResponse<BookmarkDTO>(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{id}/Tags")]
|
||||||
|
[ProducesResponseType(typeof(GenericResponse<IEnumerable<TagSummaryDTO>>), (int)HttpStatusCode.OK)]
|
||||||
|
[ProducesResponseType((int)HttpStatusCode.NotFound)]
|
||||||
|
public IActionResult GetBookmarkTags(int id)
|
||||||
|
{
|
||||||
|
var result = _bookmarkService.GetBookmarkTags(id);
|
||||||
|
|
||||||
|
if (!result.IsSuccessful) return NotFound();
|
||||||
|
|
||||||
|
return Ok(new GenericResponse<IEnumerable<TagSummaryDTO>>(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpDelete("{id}")]
|
||||||
|
[ProducesResponseType(typeof(GenericResponse<int>), (int)HttpStatusCode.OK)]
|
||||||
|
[ProducesResponseType((int)HttpStatusCode.NotFound)]
|
||||||
|
public async Task<IActionResult> Delete(int id)
|
||||||
|
{
|
||||||
|
var result = await _bookmarkService.DeleteBookmark(id);
|
||||||
|
|
||||||
|
if (!result.IsSuccessful) return NotFound();
|
||||||
|
|
||||||
|
return Ok(new GenericResponse<int>(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpDelete()]
|
||||||
|
[ProducesResponseType(typeof(IEnumerable<GenericResponse<int>>), (int)HttpStatusCode.OK)]
|
||||||
|
[ProducesResponseType((int)HttpStatusCode.NotFound)]
|
||||||
|
public async Task<IActionResult> DeleteBookmarks(IEnumerable<int> ids)
|
||||||
|
{
|
||||||
|
var result = await _bookmarkService.DeleteBookmarks(ids);
|
||||||
|
|
||||||
|
if(result.All(x => !x.IsSuccessful)) return NotFound();
|
||||||
|
|
||||||
|
return Ok(result.Select((x) => new GenericResponse<int>(x)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,5 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using YABA.Common.Extensions;
|
||||||
using YABA.Common.Lookups;
|
using YABA.Common.Lookups;
|
||||||
|
|
||||||
namespace YABA.API.Extensions
|
namespace YABA.API.Extensions
|
||||||
|
|||||||
@ -43,7 +43,8 @@ builder.Services.AddApiVersioning(setup =>
|
|||||||
setup.ApiVersionReader = new UrlSegmentApiVersionReader();
|
setup.ApiVersionReader = new UrlSegmentApiVersionReader();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add services to the container.
|
// Add services to the container
|
||||||
|
builder.Services.AddHttpContextAccessor();
|
||||||
builder.Services.AddServiceProjectDependencyInjectionConfiguration(configuration);
|
builder.Services.AddServiceProjectDependencyInjectionConfiguration(configuration);
|
||||||
builder.Services.AddDataProjectDependencyInjectionConfiguration(configuration);
|
builder.Services.AddDataProjectDependencyInjectionConfiguration(configuration);
|
||||||
builder.Services.AddControllers().AddNewtonsoftJson();
|
builder.Services.AddControllers().AddNewtonsoftJson();
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using YABA.API.ViewModels;
|
using YABA.API.ViewModels;
|
||||||
using YABA.Common.DTOs;
|
using YABA.Common.DTOs;
|
||||||
|
using YABA.Common.DTOs.Tags;
|
||||||
|
|
||||||
namespace YABA.API.Settings
|
namespace YABA.API.Settings
|
||||||
{
|
{
|
||||||
|
|||||||
22
YABA.API/ViewModels/Response.cs
Normal file
22
YABA.API/ViewModels/Response.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using YABA.Common.DTOs;
|
||||||
|
using YABA.Common.Extensions;
|
||||||
|
|
||||||
|
namespace YABA.API.ViewModels
|
||||||
|
{
|
||||||
|
public class GenericResponse<T>
|
||||||
|
{
|
||||||
|
public T Entry { get; set; }
|
||||||
|
public int StatusId { get; set; }
|
||||||
|
public string StatusName { get; set; }
|
||||||
|
public string StatusMessage { get; set; }
|
||||||
|
|
||||||
|
public GenericResponse(CrudResultDTO<T> value)
|
||||||
|
{
|
||||||
|
// TODO: Find a way to bring this to AutoMapper
|
||||||
|
Entry = value.Entry;
|
||||||
|
StatusId = (int)value.CrudResult;
|
||||||
|
StatusName = value.CrudResult.ToString();
|
||||||
|
StatusMessage = value.CrudResult.GetDisplayName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,4 @@
|
|||||||
using YABA.Service.DTO;
|
|
||||||
|
|
||||||
namespace YABA.API.ViewModels
|
namespace YABA.API.ViewModels
|
||||||
{
|
{
|
||||||
public class UserResponse
|
public class UserResponse
|
||||||
@ -8,13 +7,5 @@ namespace YABA.API.ViewModels
|
|||||||
public bool IsDeleted { get; set; }
|
public bool IsDeleted { get; set; }
|
||||||
public DateTimeOffset CreatedOn { get; set; }
|
public DateTimeOffset CreatedOn { get; set; }
|
||||||
public DateTimeOffset LastModified { get; set; }
|
public DateTimeOffset LastModified { get; set; }
|
||||||
|
|
||||||
public UserResponse(UserDTO value)
|
|
||||||
{
|
|
||||||
Id = value.Id;
|
|
||||||
IsDeleted = value.IsDeleted;
|
|
||||||
CreatedOn = value.CreatedOn;
|
|
||||||
LastModified = value.LastModified;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
21
YABA.Common/DTOs/Bookmarks/BookmarkDTO.cs
Normal file
21
YABA.Common/DTOs/Bookmarks/BookmarkDTO.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using YABA.Common.DTOs.Tags;
|
||||||
|
using YABA.Common.Interfaces;
|
||||||
|
|
||||||
|
namespace YABA.Common.DTOs.Bookmarks
|
||||||
|
{
|
||||||
|
public class BookmarkDTO : IBookmark
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public DateTimeOffset CreatedOn { get; set; }
|
||||||
|
public DateTimeOffset LastModified { get; set; }
|
||||||
|
public string Title { get; set; }
|
||||||
|
public string Description { get; set; }
|
||||||
|
public string Note { get; set; }
|
||||||
|
public bool IsHidden { get; set; }
|
||||||
|
public string Url { get; set; }
|
||||||
|
public IList<TagDTO> Tags { get; set; } = new List<TagDTO>();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
13
YABA.Common/DTOs/Bookmarks/CreateBookmarkRequestDTO.cs
Normal file
13
YABA.Common/DTOs/Bookmarks/CreateBookmarkRequestDTO.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using YABA.Common.Interfaces;
|
||||||
|
|
||||||
|
namespace YABA.Common.DTOs.Bookmarks
|
||||||
|
{
|
||||||
|
public class CreateBookmarkRequestDTO : IBookmark
|
||||||
|
{
|
||||||
|
public string Title { get; set; }
|
||||||
|
public string Description { get; set; }
|
||||||
|
public string Note { get; set; }
|
||||||
|
public bool IsHidden { get; set; }
|
||||||
|
public string Url { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
13
YABA.Common/DTOs/Bookmarks/UpdateBookmarkRequestDTO.cs
Normal file
13
YABA.Common/DTOs/Bookmarks/UpdateBookmarkRequestDTO.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using YABA.Common.Interfaces;
|
||||||
|
|
||||||
|
namespace YABA.Common.DTOs.Bookmarks
|
||||||
|
{
|
||||||
|
public class UpdateBookmarkRequestDTO : IBookmark
|
||||||
|
{
|
||||||
|
public string Title { get; set; }
|
||||||
|
public string Description { get; set; }
|
||||||
|
public string Note { get; set; }
|
||||||
|
public bool IsHidden { get; set; }
|
||||||
|
public string Url { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
12
YABA.Common/DTOs/CrudResultDTO.cs
Normal file
12
YABA.Common/DTOs/CrudResultDTO.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
using YABA.Common.Extensions;
|
||||||
|
using YABA.Common.Lookups;
|
||||||
|
|
||||||
|
namespace YABA.Common.DTOs
|
||||||
|
{
|
||||||
|
public class CrudResultDTO<T>
|
||||||
|
{
|
||||||
|
public CrudResultLookup CrudResult { get; set; }
|
||||||
|
public T Entry { get; set; }
|
||||||
|
public bool IsSuccessful => CrudResult.IsCrudResultSuccessful();
|
||||||
|
}
|
||||||
|
}
|
||||||
10
YABA.Common/DTOs/Tags/TagDTO.cs
Normal file
10
YABA.Common/DTOs/Tags/TagDTO.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
namespace YABA.Common.DTOs.Tags
|
||||||
|
{
|
||||||
|
public class TagDTO
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public bool IsDeleted { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public bool IsHidden { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
9
YABA.Common/DTOs/Tags/TagSummaryDTO.cs
Normal file
9
YABA.Common/DTOs/Tags/TagSummaryDTO.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
namespace YABA.Common.DTOs.Tags
|
||||||
|
{
|
||||||
|
public class TagSummaryDTO
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
24
YABA.Common/Extensions/DictionaryExtensions.cs
Normal file
24
YABA.Common/Extensions/DictionaryExtensions.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace YABA.Common.Extensions
|
||||||
|
{
|
||||||
|
public static class DictionaryExtensions
|
||||||
|
{
|
||||||
|
public static void AddRange<K, V>(this Dictionary<K, V> source, Dictionary<K, V> collection)
|
||||||
|
{
|
||||||
|
if (collection == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("Collection is null");
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var item in collection)
|
||||||
|
{
|
||||||
|
if (!source.ContainsKey(item.Key))
|
||||||
|
{
|
||||||
|
source.Add(item.Key, item.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using YABA.Common.Attributes;
|
using YABA.Common.Attributes;
|
||||||
@ -8,6 +9,13 @@ namespace YABA.Common.Extensions
|
|||||||
{
|
{
|
||||||
public static class EnumExtensions
|
public static class EnumExtensions
|
||||||
{
|
{
|
||||||
|
private static readonly IEnumerable<CrudResultLookup> SuccessfulCrudStatuses = new List<CrudResultLookup>() {
|
||||||
|
CrudResultLookup.CreateSucceeded,
|
||||||
|
CrudResultLookup.UpdateSucceeded,
|
||||||
|
CrudResultLookup.DeleteSucceeded,
|
||||||
|
CrudResultLookup.RetrieveSuccessful
|
||||||
|
};
|
||||||
|
|
||||||
public static TAttribute GetAttribute<TAttribute>(this Enum value) where TAttribute : Attribute
|
public static TAttribute GetAttribute<TAttribute>(this Enum value) where TAttribute : Attribute
|
||||||
{
|
{
|
||||||
var enumType = value.GetType();
|
var enumType = value.GetType();
|
||||||
@ -25,5 +33,8 @@ namespace YABA.Common.Extensions
|
|||||||
return claimLookup.GetAttribute<ClaimNameAttribute>().Name;
|
return claimLookup.GetAttribute<ClaimNameAttribute>().Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool IsCrudResultSuccessful(this CrudResultLookup importStatusLookup) => SuccessfulCrudStatuses.Contains(importStatusLookup);
|
||||||
|
|
||||||
|
public static bool IsCrudResultFailure(this CrudResultLookup importStatusLookup) => !SuccessfulCrudStatuses.Contains(importStatusLookup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using YABA.Common.Extensions;
|
|
||||||
using YABA.Common.Lookups;
|
using YABA.Common.Lookups;
|
||||||
|
|
||||||
namespace YABA.API.Extensions
|
namespace YABA.Common.Extensions
|
||||||
{
|
{
|
||||||
public static class UserIdentityExtensions
|
public static class UserIdentityExtensions
|
||||||
{
|
{
|
||||||
|
public static string GetUserId(this IIdentity identity) => GetCustomClaim(identity, ClaimsLookup.UserId);
|
||||||
public static string GetAuthProviderId(this IIdentity identity) => GetCustomClaim(identity, ClaimsLookup.AuthProviderId);
|
public static string GetAuthProviderId(this IIdentity identity) => GetCustomClaim(identity, ClaimsLookup.AuthProviderId);
|
||||||
|
|
||||||
public static string GetCustomClaim(this IIdentity identity, ClaimsLookup claim)
|
public static string GetCustomClaim(this IIdentity identity, ClaimsLookup claim)
|
||||||
11
YABA.Common/Interfaces/IBookmark.cs
Normal file
11
YABA.Common/Interfaces/IBookmark.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
namespace YABA.Common.Interfaces
|
||||||
|
{
|
||||||
|
public interface IBookmark
|
||||||
|
{
|
||||||
|
public string Title { get; set; }
|
||||||
|
public string Description { get; set; }
|
||||||
|
public string Note { get; set; }
|
||||||
|
public bool IsHidden { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
34
YABA.Common/Lookups/CrudResultLookup.cs
Normal file
34
YABA.Common/Lookups/CrudResultLookup.cs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace YABA.Common.Lookups
|
||||||
|
{
|
||||||
|
public enum CrudResultLookup
|
||||||
|
{
|
||||||
|
[Display(Name = "Insert failed")]
|
||||||
|
CreateFailed = 1,
|
||||||
|
|
||||||
|
[Display(Name = "Insert succeeded")]
|
||||||
|
CreateSucceeded = 2,
|
||||||
|
|
||||||
|
[Display(Name = "Insert failed. Entry already exists")]
|
||||||
|
CreateFailedEntryExists = 3,
|
||||||
|
|
||||||
|
[Display(Name = "Update failed")]
|
||||||
|
UpdateFailed = 4,
|
||||||
|
|
||||||
|
[Display(Name = "Update succeeded")]
|
||||||
|
UpdateSucceeded = 5,
|
||||||
|
|
||||||
|
[Display(Name = "Delete failed")]
|
||||||
|
DeleteFailed = 6,
|
||||||
|
|
||||||
|
[Display(Name = "Delete succeeded")]
|
||||||
|
DeleteSucceeded = 7,
|
||||||
|
|
||||||
|
[Display(Name = "Retrieve failed")]
|
||||||
|
RetrieveFailed = 8,
|
||||||
|
|
||||||
|
[Display(Name = "Retrieve successful")]
|
||||||
|
RetrieveSuccessful = 9
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -32,12 +32,15 @@ namespace YABA.Data.Context
|
|||||||
});
|
});
|
||||||
|
|
||||||
modelBuilder.Entity<BookmarkTag>()
|
modelBuilder.Entity<BookmarkTag>()
|
||||||
.HasIndex(x => new { x.BookmarkId, x.TagId })
|
.HasKey(x => new { x.BookmarkId, x.TagId });
|
||||||
.IsUnique();
|
|
||||||
|
|
||||||
modelBuilder.Entity<User>()
|
modelBuilder.Entity<User>()
|
||||||
.HasIndex(x => x.Auth0Id)
|
.HasIndex(x => x.Auth0Id)
|
||||||
.IsUnique();
|
.IsUnique();
|
||||||
|
|
||||||
|
modelBuilder.Entity<Tag>()
|
||||||
|
.HasIndex(x => x.Name)
|
||||||
|
.IsUnique();
|
||||||
}
|
}
|
||||||
|
|
||||||
public DbSet<Bookmark> Bookmarks { get; set; }
|
public DbSet<Bookmark> Bookmarks { get; set; }
|
||||||
|
|||||||
23
YABA.Data/Extensions/UsersDbSetExtensions.cs
Normal file
23
YABA.Data/Extensions/UsersDbSetExtensions.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using YABA.Models;
|
||||||
|
|
||||||
|
namespace YABA.Data.Extensions
|
||||||
|
{
|
||||||
|
public static class UsersDbSetExtensions
|
||||||
|
{
|
||||||
|
public static async Task<bool> UserExistsAsync(this DbSet<User> userDbSet, int userId)
|
||||||
|
{
|
||||||
|
return await userDbSet.AnyAsync(x => x.Id == userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool UserExists(this DbSet<User> userDbSet, int userId)
|
||||||
|
{
|
||||||
|
return userDbSet.Any(x => x.Id == userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
226
YABA.Data/Migrations/20230126050046_AddedUrlToBookmark.Designer.cs
generated
Normal file
226
YABA.Data/Migrations/20230126050046_AddedUrlToBookmark.Designer.cs
generated
Normal file
@ -0,0 +1,226 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
using YABA.Data.Context;
|
||||||
|
|
||||||
|
namespace YABA.Data.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(YABABaseContext))]
|
||||||
|
[Migration("20230126050046_AddedUrlToBookmark")]
|
||||||
|
partial class AddedUrlToBookmark
|
||||||
|
{
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 63)
|
||||||
|
.HasAnnotation("ProductVersion", "5.0.17")
|
||||||
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
|
modelBuilder.Entity("YABA.Models.Bookmark", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("id")
|
||||||
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("CreatedOn")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("created_on");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("description");
|
||||||
|
|
||||||
|
b.Property<bool>("IsDeleted")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("is_deleted");
|
||||||
|
|
||||||
|
b.Property<bool>("IsHidden")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("is_hidden");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("LastModified")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("last_modified");
|
||||||
|
|
||||||
|
b.Property<string>("Note")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("note");
|
||||||
|
|
||||||
|
b.Property<string>("Title")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("title");
|
||||||
|
|
||||||
|
b.Property<string>("Url")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("url");
|
||||||
|
|
||||||
|
b.Property<int>("UserId")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("user_id");
|
||||||
|
|
||||||
|
b.HasKey("Id")
|
||||||
|
.HasName("pk_bookmarks");
|
||||||
|
|
||||||
|
b.HasIndex("UserId")
|
||||||
|
.HasDatabaseName("ix_bookmarks_user_id");
|
||||||
|
|
||||||
|
b.ToTable("bookmarks");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("YABA.Models.BookmarkTag", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("id")
|
||||||
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
|
b.Property<int>("BookmarkId")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("bookmark_id");
|
||||||
|
|
||||||
|
b.Property<int>("TagId")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("tag_id");
|
||||||
|
|
||||||
|
b.HasKey("Id")
|
||||||
|
.HasName("pk_bookmark_tags");
|
||||||
|
|
||||||
|
b.HasIndex("TagId")
|
||||||
|
.HasDatabaseName("ix_bookmark_tags_tag_id");
|
||||||
|
|
||||||
|
b.HasIndex("BookmarkId", "TagId")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("ix_bookmark_tags_bookmark_id_tag_id");
|
||||||
|
|
||||||
|
b.ToTable("bookmark_tags");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("YABA.Models.Tag", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("id")
|
||||||
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
|
b.Property<bool>("IsDeleted")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("is_deleted");
|
||||||
|
|
||||||
|
b.Property<bool>("IsHidden")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("is_hidden");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("name");
|
||||||
|
|
||||||
|
b.Property<int>("UserId")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("user_id");
|
||||||
|
|
||||||
|
b.HasKey("Id")
|
||||||
|
.HasName("pk_tags");
|
||||||
|
|
||||||
|
b.HasIndex("UserId")
|
||||||
|
.HasDatabaseName("ix_tags_user_id");
|
||||||
|
|
||||||
|
b.ToTable("tags");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("YABA.Models.User", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("id")
|
||||||
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
|
b.Property<string>("Auth0Id")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("auth0id");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("CreatedOn")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("created_on");
|
||||||
|
|
||||||
|
b.Property<bool>("IsDeleted")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("is_deleted");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("LastModified")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("last_modified");
|
||||||
|
|
||||||
|
b.HasKey("Id")
|
||||||
|
.HasName("pk_users");
|
||||||
|
|
||||||
|
b.HasIndex("Auth0Id")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("ix_users_auth0id");
|
||||||
|
|
||||||
|
b.ToTable("users");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("YABA.Models.Bookmark", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("YABA.Models.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.HasConstraintName("fk_bookmarks_users_user_id")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("YABA.Models.BookmarkTag", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("YABA.Models.Bookmark", "Bookmark")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("BookmarkId")
|
||||||
|
.HasConstraintName("fk_bookmark_tags_bookmarks_bookmark_id")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("YABA.Models.Tag", "Tag")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("TagId")
|
||||||
|
.HasConstraintName("fk_bookmark_tags_tags_tag_id")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Bookmark");
|
||||||
|
|
||||||
|
b.Navigation("Tag");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("YABA.Models.Tag", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("YABA.Models.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.HasConstraintName("fk_tags_users_user_id")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
24
YABA.Data/Migrations/20230126050046_AddedUrlToBookmark.cs
Normal file
24
YABA.Data/Migrations/20230126050046_AddedUrlToBookmark.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace YABA.Data.Migrations
|
||||||
|
{
|
||||||
|
public partial class AddedUrlToBookmark : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "url",
|
||||||
|
table: "bookmarks",
|
||||||
|
type: "text",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: "");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "url",
|
||||||
|
table: "bookmarks");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,212 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
using YABA.Data.Context;
|
||||||
|
|
||||||
|
namespace YABA.Data.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(YABABaseContext))]
|
||||||
|
[Migration("20230128064541_ModifiedBookmarkTagsPK_RemovedSoftDeleteFromTagsAndBookmarks")]
|
||||||
|
partial class ModifiedBookmarkTagsPK_RemovedSoftDeleteFromTagsAndBookmarks
|
||||||
|
{
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 63)
|
||||||
|
.HasAnnotation("ProductVersion", "5.0.17")
|
||||||
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
|
modelBuilder.Entity("YABA.Models.Bookmark", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("id")
|
||||||
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("CreatedOn")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("created_on");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("description");
|
||||||
|
|
||||||
|
b.Property<bool>("IsHidden")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("is_hidden");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("LastModified")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("last_modified");
|
||||||
|
|
||||||
|
b.Property<string>("Note")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("note");
|
||||||
|
|
||||||
|
b.Property<string>("Title")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("title");
|
||||||
|
|
||||||
|
b.Property<string>("Url")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("url");
|
||||||
|
|
||||||
|
b.Property<int>("UserId")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("user_id");
|
||||||
|
|
||||||
|
b.HasKey("Id")
|
||||||
|
.HasName("pk_bookmarks");
|
||||||
|
|
||||||
|
b.HasIndex("UserId")
|
||||||
|
.HasDatabaseName("ix_bookmarks_user_id");
|
||||||
|
|
||||||
|
b.ToTable("bookmarks");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("YABA.Models.BookmarkTag", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("BookmarkId")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("bookmark_id");
|
||||||
|
|
||||||
|
b.Property<int>("TagId")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("tag_id");
|
||||||
|
|
||||||
|
b.HasKey("BookmarkId", "TagId")
|
||||||
|
.HasName("pk_bookmark_tags");
|
||||||
|
|
||||||
|
b.HasIndex("TagId")
|
||||||
|
.HasDatabaseName("ix_bookmark_tags_tag_id");
|
||||||
|
|
||||||
|
b.ToTable("bookmark_tags");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("YABA.Models.Tag", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("id")
|
||||||
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
|
b.Property<bool>("IsHidden")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("is_hidden");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("name");
|
||||||
|
|
||||||
|
b.Property<int>("UserId")
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("user_id");
|
||||||
|
|
||||||
|
b.HasKey("Id")
|
||||||
|
.HasName("pk_tags");
|
||||||
|
|
||||||
|
b.HasIndex("Name")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("ix_tags_name");
|
||||||
|
|
||||||
|
b.HasIndex("UserId")
|
||||||
|
.HasDatabaseName("ix_tags_user_id");
|
||||||
|
|
||||||
|
b.ToTable("tags");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("YABA.Models.User", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("id")
|
||||||
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
|
b.Property<string>("Auth0Id")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("auth0id");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("CreatedOn")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("created_on");
|
||||||
|
|
||||||
|
b.Property<bool>("IsDeleted")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("is_deleted");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("LastModified")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("last_modified");
|
||||||
|
|
||||||
|
b.HasKey("Id")
|
||||||
|
.HasName("pk_users");
|
||||||
|
|
||||||
|
b.HasIndex("Auth0Id")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("ix_users_auth0id");
|
||||||
|
|
||||||
|
b.ToTable("users");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("YABA.Models.Bookmark", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("YABA.Models.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.HasConstraintName("fk_bookmarks_users_user_id")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("YABA.Models.BookmarkTag", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("YABA.Models.Bookmark", "Bookmark")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("BookmarkId")
|
||||||
|
.HasConstraintName("fk_bookmark_tags_bookmarks_bookmark_id")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("YABA.Models.Tag", "Tag")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("TagId")
|
||||||
|
.HasConstraintName("fk_bookmark_tags_tags_tag_id")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Bookmark");
|
||||||
|
|
||||||
|
b.Navigation("Tag");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("YABA.Models.Tag", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("YABA.Models.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.HasConstraintName("fk_tags_users_user_id")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,86 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
namespace YABA.Data.Migrations
|
||||||
|
{
|
||||||
|
public partial class ModifiedBookmarkTagsPK_RemovedSoftDeleteFromTagsAndBookmarks : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropPrimaryKey(
|
||||||
|
name: "pk_bookmark_tags",
|
||||||
|
table: "bookmark_tags");
|
||||||
|
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "ix_bookmark_tags_bookmark_id_tag_id",
|
||||||
|
table: "bookmark_tags");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "is_deleted",
|
||||||
|
table: "tags");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "is_deleted",
|
||||||
|
table: "bookmarks");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "id",
|
||||||
|
table: "bookmark_tags");
|
||||||
|
|
||||||
|
migrationBuilder.AddPrimaryKey(
|
||||||
|
name: "pk_bookmark_tags",
|
||||||
|
table: "bookmark_tags",
|
||||||
|
columns: new[] { "bookmark_id", "tag_id" });
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_tags_name",
|
||||||
|
table: "tags",
|
||||||
|
column: "name",
|
||||||
|
unique: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "ix_tags_name",
|
||||||
|
table: "tags");
|
||||||
|
|
||||||
|
migrationBuilder.DropPrimaryKey(
|
||||||
|
name: "pk_bookmark_tags",
|
||||||
|
table: "bookmark_tags");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "is_deleted",
|
||||||
|
table: "tags",
|
||||||
|
type: "boolean",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "is_deleted",
|
||||||
|
table: "bookmarks",
|
||||||
|
type: "boolean",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "id",
|
||||||
|
table: "bookmark_tags",
|
||||||
|
type: "integer",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0)
|
||||||
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
|
migrationBuilder.AddPrimaryKey(
|
||||||
|
name: "pk_bookmark_tags",
|
||||||
|
table: "bookmark_tags",
|
||||||
|
column: "id");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_bookmark_tags_bookmark_id_tag_id",
|
||||||
|
table: "bookmark_tags",
|
||||||
|
columns: new[] { "bookmark_id", "tag_id" },
|
||||||
|
unique: true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -36,10 +36,6 @@ namespace YABA.Data.Migrations
|
|||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("description");
|
.HasColumnName("description");
|
||||||
|
|
||||||
b.Property<bool>("IsDeleted")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("is_deleted");
|
|
||||||
|
|
||||||
b.Property<bool>("IsHidden")
|
b.Property<bool>("IsHidden")
|
||||||
.HasColumnType("boolean")
|
.HasColumnType("boolean")
|
||||||
.HasColumnName("is_hidden");
|
.HasColumnName("is_hidden");
|
||||||
@ -58,6 +54,11 @@ namespace YABA.Data.Migrations
|
|||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("title");
|
.HasColumnName("title");
|
||||||
|
|
||||||
|
b.Property<string>("Url")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("url");
|
||||||
|
|
||||||
b.Property<int>("UserId")
|
b.Property<int>("UserId")
|
||||||
.HasColumnType("integer")
|
.HasColumnType("integer")
|
||||||
.HasColumnName("user_id");
|
.HasColumnName("user_id");
|
||||||
@ -73,12 +74,6 @@ namespace YABA.Data.Migrations
|
|||||||
|
|
||||||
modelBuilder.Entity("YABA.Models.BookmarkTag", b =>
|
modelBuilder.Entity("YABA.Models.BookmarkTag", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
|
||||||
.ValueGeneratedOnAdd()
|
|
||||||
.HasColumnType("integer")
|
|
||||||
.HasColumnName("id")
|
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
|
||||||
|
|
||||||
b.Property<int>("BookmarkId")
|
b.Property<int>("BookmarkId")
|
||||||
.HasColumnType("integer")
|
.HasColumnType("integer")
|
||||||
.HasColumnName("bookmark_id");
|
.HasColumnName("bookmark_id");
|
||||||
@ -87,16 +82,12 @@ namespace YABA.Data.Migrations
|
|||||||
.HasColumnType("integer")
|
.HasColumnType("integer")
|
||||||
.HasColumnName("tag_id");
|
.HasColumnName("tag_id");
|
||||||
|
|
||||||
b.HasKey("Id")
|
b.HasKey("BookmarkId", "TagId")
|
||||||
.HasName("pk_bookmark_tags");
|
.HasName("pk_bookmark_tags");
|
||||||
|
|
||||||
b.HasIndex("TagId")
|
b.HasIndex("TagId")
|
||||||
.HasDatabaseName("ix_bookmark_tags_tag_id");
|
.HasDatabaseName("ix_bookmark_tags_tag_id");
|
||||||
|
|
||||||
b.HasIndex("BookmarkId", "TagId")
|
|
||||||
.IsUnique()
|
|
||||||
.HasDatabaseName("ix_bookmark_tags_bookmark_id_tag_id");
|
|
||||||
|
|
||||||
b.ToTable("bookmark_tags");
|
b.ToTable("bookmark_tags");
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -108,10 +99,6 @@ namespace YABA.Data.Migrations
|
|||||||
.HasColumnName("id")
|
.HasColumnName("id")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<bool>("IsDeleted")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("is_deleted");
|
|
||||||
|
|
||||||
b.Property<bool>("IsHidden")
|
b.Property<bool>("IsHidden")
|
||||||
.HasColumnType("boolean")
|
.HasColumnType("boolean")
|
||||||
.HasColumnName("is_hidden");
|
.HasColumnName("is_hidden");
|
||||||
@ -128,6 +115,10 @@ namespace YABA.Data.Migrations
|
|||||||
b.HasKey("Id")
|
b.HasKey("Id")
|
||||||
.HasName("pk_tags");
|
.HasName("pk_tags");
|
||||||
|
|
||||||
|
b.HasIndex("Name")
|
||||||
|
.IsUnique()
|
||||||
|
.HasDatabaseName("ix_tags_name");
|
||||||
|
|
||||||
b.HasIndex("UserId")
|
b.HasIndex("UserId")
|
||||||
.HasDatabaseName("ix_tags_user_id");
|
.HasDatabaseName("ix_tags_user_id");
|
||||||
|
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\YABA.Common\YABA.Common.csproj" />
|
||||||
<ProjectReference Include="..\YABA.Models\YABA.Models.csproj" />
|
<ProjectReference Include="..\YABA.Models\YABA.Models.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
@ -1,20 +1,21 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using YABA.Common.Interfaces;
|
||||||
using YABA.Models.Interfaces;
|
using YABA.Models.Interfaces;
|
||||||
|
|
||||||
namespace YABA.Models
|
namespace YABA.Models
|
||||||
{
|
{
|
||||||
public class Bookmark : IIdentifiable, ISoftDeletable, IDateCreatedTrackable, IDateModifiedTrackable
|
public class Bookmark : IIdentifiable, IDateCreatedTrackable, IDateModifiedTrackable, IBookmark
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
public bool IsDeleted { get; set; }
|
|
||||||
public DateTimeOffset CreatedOn { get; set; }
|
public DateTimeOffset CreatedOn { get; set; }
|
||||||
public DateTimeOffset LastModified { get; set; }
|
public DateTimeOffset LastModified { get; set; }
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
public string Description { get; set; }
|
public string Description { get; set; }
|
||||||
public string Note { get; set; }
|
public string Note { get; set; }
|
||||||
public bool IsHidden { get; set; }
|
public bool IsHidden { get; set; }
|
||||||
|
public string Url { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
[ForeignKey(nameof(User))]
|
[ForeignKey(nameof(User))]
|
||||||
|
|||||||
@ -1,13 +1,10 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using YABA.Models.Interfaces;
|
|
||||||
|
|
||||||
namespace YABA.Models
|
namespace YABA.Models
|
||||||
{
|
{
|
||||||
public class BookmarkTag : IIdentifiable
|
public class BookmarkTag
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
[ForeignKey(nameof(Bookmark))]
|
[ForeignKey(nameof(Bookmark))]
|
||||||
public int BookmarkId { get; set; }
|
public int BookmarkId { get; set; }
|
||||||
|
|||||||
@ -4,10 +4,9 @@ using YABA.Models.Interfaces;
|
|||||||
|
|
||||||
namespace YABA.Models
|
namespace YABA.Models
|
||||||
{
|
{
|
||||||
public class Tag : IIdentifiable, ISoftDeletable
|
public class Tag : IIdentifiable
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
public bool IsDeleted { get; set; }
|
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public bool IsHidden { get; set; }
|
public bool IsHidden { get; set; }
|
||||||
|
|
||||||
|
|||||||
@ -9,4 +9,8 @@
|
|||||||
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\YABA.Common\YABA.Common.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
232
YABA.Service/BookmarkService.cs
Normal file
232
YABA.Service/BookmarkService.cs
Normal file
@ -0,0 +1,232 @@
|
|||||||
|
using AutoMapper;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using YABA.Common.DTOs;
|
||||||
|
using YABA.Common.DTOs.Bookmarks;
|
||||||
|
using YABA.Common.DTOs.Tags;
|
||||||
|
using YABA.Common.Extensions;
|
||||||
|
using YABA.Common.Interfaces;
|
||||||
|
using YABA.Common.Lookups;
|
||||||
|
using YABA.Data.Context;
|
||||||
|
using YABA.Data.Extensions;
|
||||||
|
using YABA.Models;
|
||||||
|
using YABA.Service.Interfaces;
|
||||||
|
|
||||||
|
namespace YABA.Service
|
||||||
|
{
|
||||||
|
public class BookmarkService : IBookmarkService
|
||||||
|
{
|
||||||
|
private readonly YABAReadOnlyContext _roContext;
|
||||||
|
private readonly YABAReadWriteContext _context;
|
||||||
|
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||||
|
private readonly IMapper _mapper;
|
||||||
|
|
||||||
|
public BookmarkService(
|
||||||
|
YABAReadOnlyContext roContext,
|
||||||
|
YABAReadWriteContext context,
|
||||||
|
IHttpContextAccessor httpContextAccessor,
|
||||||
|
IMapper mapper)
|
||||||
|
{
|
||||||
|
_roContext = roContext;
|
||||||
|
_context = context;
|
||||||
|
_mapper = mapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CrudResultDTO<IEnumerable<BookmarkDTO>> GetAll()
|
||||||
|
{
|
||||||
|
var currentUserId = GetCurrentUserId();
|
||||||
|
|
||||||
|
var bookmarkTagsLookup = _roContext.BookmarkTags
|
||||||
|
.Where(x => x.Bookmark.UserId == currentUserId)
|
||||||
|
.GroupBy(x => x.BookmarkId)
|
||||||
|
.ToDictionary(key => key.Key, value => value.Select(x => x.TagId));
|
||||||
|
|
||||||
|
var bookmarksLookup = _roContext.Bookmarks
|
||||||
|
.Where(x => bookmarkTagsLookup.Keys.Contains(x.Id))
|
||||||
|
.ToDictionary(key => key.Id, value => value);
|
||||||
|
|
||||||
|
var tagsLookup = _roContext.Tags
|
||||||
|
.Where(x => bookmarkTagsLookup.Values.SelectMany(y => y.ToList()).Contains(x.Id))
|
||||||
|
.ToDictionary(key => key.Id, value => value);
|
||||||
|
|
||||||
|
var bookmarks = new List<BookmarkDTO>();
|
||||||
|
|
||||||
|
foreach(var bookmarkTagLookup in bookmarkTagsLookup)
|
||||||
|
{
|
||||||
|
var bookmarkExists = bookmarksLookup.TryGetValue(bookmarkTagLookup.Key, out Bookmark bookmark);
|
||||||
|
|
||||||
|
if (!bookmarkExists) continue;
|
||||||
|
|
||||||
|
var bookmarkDTO = _mapper.Map<BookmarkDTO>(bookmark);
|
||||||
|
|
||||||
|
foreach(var tagId in bookmarkTagLookup.Value)
|
||||||
|
{
|
||||||
|
var tagExists = tagsLookup.TryGetValue(tagId, out Tag tag);
|
||||||
|
|
||||||
|
if (!tagExists) continue;
|
||||||
|
|
||||||
|
var tagDTO = _mapper.Map<TagDTO>(tag);
|
||||||
|
bookmarkDTO.Tags.Add(tagDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
bookmarks.Add(bookmarkDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new CrudResultDTO<IEnumerable<BookmarkDTO>> { Entry = bookmarks, CrudResult = CrudResultLookup.RetrieveSuccessful };
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<CrudResultDTO<CreateBookmarkRequestDTO>?> CreateBookmark(CreateBookmarkRequestDTO request)
|
||||||
|
{
|
||||||
|
var crudResult = new CrudResultDTO<CreateBookmarkRequestDTO>() { Entry = request, CrudResult = CrudResultLookup.CreateFailed };
|
||||||
|
var currentUserId = GetCurrentUserId();
|
||||||
|
|
||||||
|
if (!_roContext.Users.UserExists(currentUserId)) return crudResult;
|
||||||
|
|
||||||
|
if(await _roContext.Bookmarks.AnyAsync(x => x.UserId == currentUserId && x.Url == request.Url))
|
||||||
|
{
|
||||||
|
crudResult.CrudResult = CrudResultLookup.CreateFailedEntryExists;
|
||||||
|
return crudResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
var bookmark = _mapper.Map<Bookmark>(request);
|
||||||
|
bookmark.UserId = currentUserId;
|
||||||
|
|
||||||
|
await _context.Bookmarks.AddAsync(bookmark);
|
||||||
|
|
||||||
|
if (await _context.SaveChangesAsync() > 0) crudResult.CrudResult = CrudResultLookup.CreateSucceeded;
|
||||||
|
|
||||||
|
return crudResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<CrudResultDTO<UpdateBookmarkRequestDTO>> UpdateBookmark(int id, UpdateBookmarkRequestDTO request)
|
||||||
|
{
|
||||||
|
var crudResult = new CrudResultDTO<UpdateBookmarkRequestDTO>() { Entry = request, CrudResult = CrudResultLookup.UpdateFailed };
|
||||||
|
var currentUserId = GetCurrentUserId();
|
||||||
|
|
||||||
|
if (!_roContext.Users.UserExists(currentUserId)) return crudResult;
|
||||||
|
|
||||||
|
var bookmark = _context.Bookmarks.FirstOrDefault(x => x.UserId == currentUserId && x.Id == id);
|
||||||
|
|
||||||
|
if(bookmark == null) return crudResult;
|
||||||
|
|
||||||
|
bookmark.Title = request.Title;
|
||||||
|
bookmark.Description = request.Description;
|
||||||
|
bookmark.Note = request.Note;
|
||||||
|
bookmark.IsHidden = request.IsHidden;
|
||||||
|
bookmark.Url = request.Url;
|
||||||
|
|
||||||
|
if (await _context.SaveChangesAsync() > 0) crudResult.CrudResult = CrudResultLookup.UpdateSucceeded;
|
||||||
|
|
||||||
|
return crudResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<CrudResultDTO<string>>> UpdateBookmarkTags(int id, IEnumerable<string> tags)
|
||||||
|
{
|
||||||
|
var crudResults = tags.Select((x) => new CrudResultDTO<string> { Entry = x, CrudResult = CrudResultLookup.UpdateFailed }).ToList();
|
||||||
|
var currentUserId = GetCurrentUserId();
|
||||||
|
|
||||||
|
if (!_roContext.Bookmarks.Any(x => x.Id == id && x.UserId == currentUserId)) return crudResults;
|
||||||
|
|
||||||
|
// Add tags that are not yet in the database
|
||||||
|
var savedUserTags = _context.Tags.Where(x => x.UserId == currentUserId).ToList();
|
||||||
|
var tagsToSave = tags.Except(savedUserTags.Select(x => x.Name).ToHashSet()).Select(x => new Tag { Name = x, UserId = currentUserId });
|
||||||
|
await _context.Tags.AddRangeAsync(tagsToSave);
|
||||||
|
|
||||||
|
if (await _context.SaveChangesAsync() <= 0) return crudResults;
|
||||||
|
|
||||||
|
// Add newly added tags to the lookup
|
||||||
|
savedUserTags.AddRange(tagsToSave);
|
||||||
|
|
||||||
|
var existingBookmarkTags = _context.BookmarkTags.Include(x => x.Tag).Where(x => x.BookmarkId == id).ToList();
|
||||||
|
var existingBookmarkTagsLookup = existingBookmarkTags.ToDictionary(k => k.TagId, v => v.Tag.Name);
|
||||||
|
|
||||||
|
var bookmarkTagsToRemove = existingBookmarkTagsLookup
|
||||||
|
.Where(x => !tags.Contains(x.Value))
|
||||||
|
.Select(x => new BookmarkTag { BookmarkId = id, TagId = x.Key });
|
||||||
|
|
||||||
|
var savedUserTagsByName = savedUserTags.ToDictionary(k => k.Name, v => v.Id);
|
||||||
|
var bookmarkTagsToAdd = tags.Except(existingBookmarkTagsLookup.Values)
|
||||||
|
.Select(x => new BookmarkTag { BookmarkId = id, TagId = savedUserTagsByName[x] });
|
||||||
|
|
||||||
|
_context.BookmarkTags.RemoveRange(bookmarkTagsToRemove);
|
||||||
|
await _context.BookmarkTags.AddRangeAsync(bookmarkTagsToAdd);
|
||||||
|
|
||||||
|
if (await _context.SaveChangesAsync() >= 0) crudResults.ForEach(x => x.CrudResult = CrudResultLookup.UpdateSucceeded);
|
||||||
|
|
||||||
|
return crudResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<CrudResultDTO<BookmarkDTO>> Get(int id)
|
||||||
|
{
|
||||||
|
int.TryParse(_httpContextAccessor.HttpContext.User.Identity.GetUserId(), out int userId);
|
||||||
|
var bookmark = await _roContext.Bookmarks.FirstOrDefaultAsync(x => x.Id == id && x.UserId == userId);
|
||||||
|
|
||||||
|
if (bookmark == null) return new CrudResultDTO<BookmarkDTO> { CrudResult = CrudResultLookup.RetrieveFailed, Entry = null };
|
||||||
|
|
||||||
|
var bookmarkTags = _roContext.BookmarkTags
|
||||||
|
.Include(x => x.Tag)
|
||||||
|
.Where(x => x.BookmarkId == id)
|
||||||
|
.Select(x => x.Tag)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
var bookmarkDTO = _mapper.Map<BookmarkDTO>(bookmark);
|
||||||
|
bookmarkDTO.Tags = _mapper.Map<IList<TagDTO>>(bookmarkTags);
|
||||||
|
|
||||||
|
return new CrudResultDTO<BookmarkDTO> { CrudResult = CrudResultLookup.RetrieveSuccessful, Entry = bookmarkDTO };
|
||||||
|
}
|
||||||
|
|
||||||
|
public CrudResultDTO<IEnumerable<TagSummaryDTO>> GetBookmarkTags(int id)
|
||||||
|
{
|
||||||
|
int.TryParse(_httpContextAccessor.HttpContext.User.Identity.GetUserId(), out int userId);
|
||||||
|
if (!_roContext.Bookmarks.Any(x => x.Id == id && x.UserId == userId)) return new CrudResultDTO<IEnumerable<TagSummaryDTO>> { Entry = null, CrudResult = CrudResultLookup.RetrieveFailed };
|
||||||
|
|
||||||
|
var bookmarkTags = _roContext.BookmarkTags
|
||||||
|
.Include(x => x.Tag)
|
||||||
|
.Where(x => x.BookmarkId == id)
|
||||||
|
.Select(x => x.Tag)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
var bookmarkTagDTOs = _mapper.Map<IEnumerable<TagSummaryDTO>>(bookmarkTags);
|
||||||
|
|
||||||
|
return new CrudResultDTO<IEnumerable<TagSummaryDTO>> { Entry = bookmarkTagDTOs, CrudResult = CrudResultLookup.RetrieveSuccessful };
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<CrudResultDTO<int>> DeleteBookmark(int id)
|
||||||
|
{
|
||||||
|
var crudResults = await DeleteBookmarks(new List<int> { id });
|
||||||
|
return crudResults.FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<CrudResultDTO<int>>> DeleteBookmarks(IEnumerable<int> ids)
|
||||||
|
{
|
||||||
|
var crudResults = ids.Select(x => new CrudResultDTO<int> { Entry = x, CrudResult = CrudResultLookup.DeleteFailed }).ToList();
|
||||||
|
var currentUserId = GetCurrentUserId();
|
||||||
|
|
||||||
|
if (!await _roContext.Users.UserExistsAsync(currentUserId)) return crudResults;
|
||||||
|
|
||||||
|
var entriesToDelete = _context.Bookmarks.Where(x => x.UserId == currentUserId && ids.Contains(x.Id)).ToList();
|
||||||
|
var entryIdsToDelete = entriesToDelete.Select(x => x.Id);
|
||||||
|
_context.Bookmarks.RemoveRange(entriesToDelete);
|
||||||
|
|
||||||
|
if (await _context.SaveChangesAsync() <= 0) return crudResults;
|
||||||
|
|
||||||
|
// Update crudResults that were found in the entriesToDelete to success
|
||||||
|
foreach(var crudResult in crudResults)
|
||||||
|
{
|
||||||
|
if (entryIdsToDelete.Contains(crudResult.Entry))
|
||||||
|
crudResult.CrudResult = CrudResultLookup.DeleteSucceeded;
|
||||||
|
}
|
||||||
|
|
||||||
|
return crudResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetCurrentUserId()
|
||||||
|
{
|
||||||
|
int.TryParse(_httpContextAccessor.HttpContext.User.Identity.GetUserId(), out int userId);
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,7 @@
|
|||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using YABA.Common.DTOs;
|
using YABA.Common.DTOs;
|
||||||
|
using YABA.Common.DTOs.Bookmarks;
|
||||||
|
using YABA.Common.DTOs.Tags;
|
||||||
using YABA.Models;
|
using YABA.Models;
|
||||||
|
|
||||||
namespace YABA.Service.Configuration
|
namespace YABA.Service.Configuration
|
||||||
@ -9,6 +11,11 @@ namespace YABA.Service.Configuration
|
|||||||
public AutoMapperProfile()
|
public AutoMapperProfile()
|
||||||
{
|
{
|
||||||
CreateMap<User, UserDTO>();
|
CreateMap<User, UserDTO>();
|
||||||
|
CreateMap<BookmarkDTO, Bookmark>();
|
||||||
|
CreateMap<Bookmark, BookmarkDTO>();
|
||||||
|
CreateMap<CreateBookmarkRequestDTO, Bookmark>();
|
||||||
|
CreateMap<Tag, TagDTO>();
|
||||||
|
CreateMap<Tag, TagSummaryDTO>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,6 +9,7 @@ namespace YABA.Service.Configuration
|
|||||||
public static void AddServiceProjectDependencyInjectionConfiguration(this IServiceCollection services, IConfiguration configuration)
|
public static void AddServiceProjectDependencyInjectionConfiguration(this IServiceCollection services, IConfiguration configuration)
|
||||||
{
|
{
|
||||||
services.AddScoped<IUserService, UserService>();
|
services.AddScoped<IUserService, UserService>();
|
||||||
|
services.AddScoped<IBookmarkService, BookmarkService>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
21
YABA.Service/Interfaces/IBookmarkService.cs
Normal file
21
YABA.Service/Interfaces/IBookmarkService.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using YABA.Common.DTOs;
|
||||||
|
using YABA.Common.DTOs.Bookmarks;
|
||||||
|
using YABA.Common.DTOs.Tags;
|
||||||
|
|
||||||
|
namespace YABA.Service.Interfaces
|
||||||
|
{
|
||||||
|
public interface IBookmarkService
|
||||||
|
{
|
||||||
|
Task<CrudResultDTO<CreateBookmarkRequestDTO>> CreateBookmark(CreateBookmarkRequestDTO request);
|
||||||
|
Task<CrudResultDTO<UpdateBookmarkRequestDTO>> UpdateBookmark(int id, UpdateBookmarkRequestDTO request);
|
||||||
|
Task<IEnumerable<CrudResultDTO<string>>> UpdateBookmarkTags(int id, IEnumerable<string> tags);
|
||||||
|
CrudResultDTO<IEnumerable<BookmarkDTO>> GetAll();
|
||||||
|
Task<CrudResultDTO<BookmarkDTO>> Get(int id);
|
||||||
|
CrudResultDTO<IEnumerable<TagSummaryDTO>> GetBookmarkTags(int id);
|
||||||
|
Task<CrudResultDTO<int>> DeleteBookmark(int id);
|
||||||
|
Task<IEnumerable<CrudResultDTO<int>>> DeleteBookmarks(IEnumerable<int> ids);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AutoMapper" Version="12.0.1" />
|
<PackageReference Include="AutoMapper" Version="12.0.1" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="7.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="7.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
Reference in New Issue
Block a user