| @@ -5,27 +5,27 @@ namespace Diligent.WebAPI.Business.Extensions | |||
| [ExcludeFromCodeCoverage] | |||
| public static class FileExtensions | |||
| { | |||
| public static IQueryable<FileEntity> FilterByExtension(this IQueryable<FileEntity> query, string[]? values) | |||
| public static List<FileFilterReturnDto> FilterByExtension(this List<FileFilterReturnDto> query, string[]? values) | |||
| { | |||
| if (values == null || values.Length == 0) | |||
| return query; | |||
| return query.Where(n => values.Contains(n.Extension)); | |||
| return query.Where(n => values.Contains(n.file_type)).ToList(); | |||
| } | |||
| public static IQueryable<FileEntity> FilterByCategory(this IQueryable<FileEntity> query, string[]? values) | |||
| public static List<FileFilterReturnDto> FilterByCategory(this List<FileFilterReturnDto> query, string[]? values) | |||
| { | |||
| if (values == null || values.Length == 0) | |||
| return query; | |||
| return query.Where(n => values.Contains(n.Category.Name)); | |||
| return query.Where(n => values.Contains(n.Category.CategoryName)).ToList(); | |||
| } | |||
| public static IQueryable<FileEntity> FilterByTags(this IQueryable<FileEntity> query, string[]? values) | |||
| public static List<FileFilterReturnDto> FilterByTags(this List<FileFilterReturnDto> query, string[]? values) | |||
| { | |||
| if (values == null || values.Length == 0) | |||
| return query; | |||
| //return query.Where(n => values.Any(x => n.Tags.Any(y => y.Name == x))); | |||
| return query.Where(n => n.Tags.Any(x => values.Contains(x.Name))); | |||
| return query.Where(n => n.Tags.Any(x => values.Contains(x.TagName))).ToList(); | |||
| } | |||
| public static IQueryable<FileEntity> FilterFiles(this IQueryable<FileEntity> query, FileFilter filters) | |||
| public static List<FileFilterReturnDto> FilterFiles(this List<FileFilterReturnDto> query, FileFilter filters) | |||
| { | |||
| return query | |||
| .FilterByCategory(filters.Categories) | |||
| @@ -3,6 +3,7 @@ using Diligent.WebAPI.Contracts.DTOs.Document; | |||
| using Microsoft.AspNetCore.Http; | |||
| using Microsoft.Extensions.Configuration; | |||
| using System.Data.SqlClient; | |||
| using static System.Net.Mime.MediaTypeNames; | |||
| namespace Diligent.WebAPI.Business.Services | |||
| { | |||
| @@ -29,14 +30,19 @@ namespace Diligent.WebAPI.Business.Services | |||
| return files.ToList(); | |||
| } | |||
| public async Task UploadDocument(IFormFile file) | |||
| public async Task<DocumentReadDTO> UploadDocument(IFormFile file) | |||
| { | |||
| using var connection = new SqlConnection(_configuration.GetConnectionString("WebApi")); | |||
| var ms = new MemoryStream(); | |||
| file.CopyTo(ms); | |||
| var fileBytes = ms.ToArray(); | |||
| await connection.ExecuteAsync("insert into dbo.DocumentOrganizerDocStore (file_stream,name) values(@fileBytes,'neki2.txt')", | |||
| new { fileBytes = fileBytes }); | |||
| string fileName = string.Format(@"{0}" + $"{Path.GetExtension(file.FileName)}", DateTime.Now.Ticks); | |||
| await connection.ExecuteAsync("insert into dbo.DocumentOrganizerDocStore (file_stream,name) values(@fileBytes,@fileName)", | |||
| new { fileBytes = fileBytes, fileName = fileName }); | |||
| var fileByName = await connection.QueryFirstAsync<DocumentReadDTO>("select * from dbo.DocumentOrganizerDocStore where name=@fileName", | |||
| new { fileName = fileName }); | |||
| return fileByName; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,11 +1,18 @@ | |||
| using Azure.Core; | |||
| using Dapper; | |||
| using Diligent.WebAPI.Contracts.DTOs.Categories; | |||
| using Diligent.WebAPI.Contracts.DTOs.Document; | |||
| using Diligent.WebAPI.Contracts.DTOs.File; | |||
| using Diligent.WebAPI.Contracts.DTOs.Files; | |||
| using Diligent.WebAPI.Contracts.DTOs.Tags; | |||
| using Microsoft.Extensions.Configuration; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Data.SqlClient; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Threading.Tasks; | |||
| using static System.Net.Mime.MediaTypeNames; | |||
| namespace Diligent.WebAPI.Business.Services | |||
| { | |||
| @@ -14,12 +21,14 @@ namespace Diligent.WebAPI.Business.Services | |||
| private readonly ILogger<FileEntityService> _logger; | |||
| private readonly DatabaseContext _context; | |||
| private readonly IMapper _mapper; | |||
| private readonly IConfiguration _configuration; | |||
| public FileEntityService(DatabaseContext context, ILogger<FileEntityService> logger, IMapper mapper) | |||
| public FileEntityService(DatabaseContext context, ILogger<FileEntityService> logger, IMapper mapper, IConfiguration configuration) | |||
| { | |||
| _context = context; | |||
| _logger = logger; | |||
| _mapper = mapper; | |||
| _configuration = configuration; | |||
| } | |||
| public async Task<List<FileEntityResponse>> GetAllAsync() => | |||
| @@ -39,16 +48,24 @@ namespace Diligent.WebAPI.Business.Services | |||
| public async Task<object> GetAllFiltered(FileFilter filters) | |||
| { | |||
| var filtered = await _context.Files | |||
| .Include(n => n.Tags) | |||
| .Include(n => n.Category) | |||
| .FilterFiles(filters) | |||
| .ToListAsync(); | |||
| using var connection = new SqlConnection(_configuration.GetConnectionString("WebApi")); | |||
| var files = await connection.QueryAsync<FileFilterReturnDto, TagResponse, CategoryResponse, FileFilterReturnDto>("SELECT Files.Id as FileId, stream_id, DocumentOrganizerDocStore.name as FileName, file_stream, file_type, cached_file_size, Tags.Id as TagId, Tags.Name as TagName, Categories.Id as CategoryId, Categories.Name as CategoryName FROM Files inner join FileEntityTag on Files.Id = FileEntityTag.FilesId inner join Tags on FileEntityTag.TagsId = Tags.Id inner join DocumentOrganizerDocStore on DocumentOrganizerDocStore.stream_id = Files.DocumentId inner join Categories on Files.CategoryId = Categories.Id;", (file, tag, category) => | |||
| { | |||
| file.Tags.Add(tag); | |||
| file.Category = category; | |||
| return file; | |||
| }, splitOn: "TagId, CategoryId"); | |||
| var filesList = files.ToList(); | |||
| var filtered = filesList | |||
| .FilterFiles(filters); | |||
| return new | |||
| { | |||
| Data = filtered.ApplyPagging(filters) | |||
| .Select(n => new { n.Id, n.Name, n.Size, n.Extension}), | |||
| .Select(n => new { n.stream_id, n.FileName, n.cached_file_size, n.file_type }), | |||
| Total = filtered.Count | |||
| }; | |||
| } | |||
| @@ -7,6 +7,6 @@ namespace Diligent.WebAPI.Business.Services.Interfaces | |||
| { | |||
| Task<List<DocumentReadDTO>> GetAllDocuments(); | |||
| Task<List<DocumentReadDTO>> GetDocumentsByText(string text); | |||
| Task UploadDocument(IFormFile file); | |||
| Task<DocumentReadDTO> UploadDocument(IFormFile file); | |||
| } | |||
| } | |||
| @@ -1,7 +1,11 @@ | |||
| using Diligent.WebAPI.Contracts.DTOs.Categories; | |||
| using Dapper; | |||
| using Diligent.WebAPI.Contracts.DTOs.Categories; | |||
| using Diligent.WebAPI.Contracts.DTOs.Files; | |||
| using Diligent.WebAPI.Contracts.DTOs.Tags; | |||
| using Microsoft.EntityFrameworkCore; | |||
| using Microsoft.Extensions.Configuration; | |||
| using System.Data.SqlClient; | |||
| using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database; | |||
| namespace Diligent.WebAPI.Business.Services | |||
| { | |||
| @@ -9,25 +13,30 @@ namespace Diligent.WebAPI.Business.Services | |||
| { | |||
| private readonly DatabaseContext _databaseContext; | |||
| private readonly IMapper _mapper; | |||
| private readonly IConfiguration _configuration; | |||
| public TagService(DatabaseContext databaseContext, IMapper mapper) | |||
| public TagService(DatabaseContext databaseContext, IMapper mapper, IConfiguration configuration) | |||
| { | |||
| _databaseContext = databaseContext; | |||
| _mapper = mapper; | |||
| _configuration = configuration; | |||
| } | |||
| public async Task<FileFiltersReturnDTO> GetFilters() | |||
| { | |||
| var categories = await _databaseContext.Categories.ToArrayAsync(); | |||
| var tags = await _databaseContext.Tags.ToArrayAsync(); | |||
| var extensions = await _databaseContext.Files | |||
| .Select(m => m.Extension).Distinct().ToArrayAsync(); | |||
| using var connection = new SqlConnection(_configuration.GetConnectionString("WebApi")); | |||
| var files = await connection.QueryAsync<FileFilterReturnDto>("SELECT * FROM Files inner join DocumentOrganizerDocStore on DocumentOrganizerDocStore.stream_id = Files.DocumentId;"); | |||
| var extensionsArray = files.Select(x => x.file_type).ToArray(); | |||
| return new FileFiltersReturnDTO | |||
| { | |||
| Categories = categories, | |||
| Tags = tags, | |||
| Extensions = extensions | |||
| Extensions = extensionsArray | |||
| }; | |||
| } | |||
| @@ -10,9 +10,9 @@ namespace Diligent.WebAPI.Contracts.DTOs.Categories | |||
| { | |||
| public class CategoryResponse | |||
| { | |||
| public int Id { get; set; } | |||
| public int CategoryId { get; set; } | |||
| public string Name { get; set; } | |||
| public string CategoryName { get; set; } | |||
| public List<FileEntityResponse> Files { get; set; } | |||
| } | |||
| @@ -0,0 +1,20 @@ | |||
| using Diligent.WebAPI.Contracts.DTOs.Categories; | |||
| using Diligent.WebAPI.Contracts.DTOs.Tags; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using System.Threading.Tasks; | |||
| namespace Diligent.WebAPI.Contracts.DTOs.Files | |||
| { | |||
| public class FileFilterReturnDto | |||
| { | |||
| public Guid stream_id { get; set; } | |||
| public string FileName { get; set; } | |||
| public string file_type { get; set; } | |||
| public int cached_file_size { get; set; } | |||
| public List<TagResponse> Tags { get; set; } = new(); | |||
| public CategoryResponse Category { get; set; } | |||
| } | |||
| } | |||
| @@ -8,8 +8,8 @@ namespace Diligent.WebAPI.Contracts.DTOs.Tags | |||
| { | |||
| public class TagResponse | |||
| { | |||
| public int Id { get; set; } | |||
| public int TagId { get; set; } | |||
| public string Name { get; set; } | |||
| public string TagName { get; set; } | |||
| } | |||
| } | |||
| @@ -11,11 +11,7 @@ namespace Diligent.WebAPI.Data.Entities | |||
| { | |||
| public int Id { get; set; } | |||
| public string Name { get; set; } | |||
| public long Size { get; set; } | |||
| public string Extension { get; set; } | |||
| public Guid DocumentId { get; set; } | |||
| [ForeignKey(nameof(Category))] | |||
| public int CategoryId { get; set; } | |||
| @@ -0,0 +1,60 @@ | |||
| using System; | |||
| using Microsoft.EntityFrameworkCore.Migrations; | |||
| #nullable disable | |||
| namespace Diligent.WebAPI.Data.Migrations | |||
| { | |||
| public partial class FileEntityChanged : Migration | |||
| { | |||
| protected override void Up(MigrationBuilder migrationBuilder) | |||
| { | |||
| migrationBuilder.DropColumn( | |||
| name: "Extension", | |||
| table: "Files"); | |||
| migrationBuilder.DropColumn( | |||
| name: "Name", | |||
| table: "Files"); | |||
| migrationBuilder.DropColumn( | |||
| name: "Size", | |||
| table: "Files"); | |||
| migrationBuilder.AddColumn<Guid>( | |||
| name: "DocumentId", | |||
| table: "Files", | |||
| type: "uniqueidentifier", | |||
| nullable: false, | |||
| defaultValue: new Guid("00000000-0000-0000-0000-000000000000")); | |||
| } | |||
| protected override void Down(MigrationBuilder migrationBuilder) | |||
| { | |||
| migrationBuilder.DropColumn( | |||
| name: "DocumentId", | |||
| table: "Files"); | |||
| migrationBuilder.AddColumn<string>( | |||
| name: "Extension", | |||
| table: "Files", | |||
| type: "nvarchar(max)", | |||
| nullable: false, | |||
| defaultValue: ""); | |||
| migrationBuilder.AddColumn<string>( | |||
| name: "Name", | |||
| table: "Files", | |||
| type: "nvarchar(max)", | |||
| nullable: false, | |||
| defaultValue: ""); | |||
| migrationBuilder.AddColumn<long>( | |||
| name: "Size", | |||
| table: "Files", | |||
| type: "bigint", | |||
| nullable: false, | |||
| defaultValue: 0L); | |||
| } | |||
| } | |||
| } | |||
| @@ -260,16 +260,8 @@ namespace Diligent.WebAPI.Data.Migrations | |||
| b.Property<int>("CategoryId") | |||
| .HasColumnType("int"); | |||
| b.Property<string>("Extension") | |||
| .IsRequired() | |||
| .HasColumnType("nvarchar(max)"); | |||
| b.Property<string>("Name") | |||
| .IsRequired() | |||
| .HasColumnType("nvarchar(max)"); | |||
| b.Property<long>("Size") | |||
| .HasColumnType("bigint"); | |||
| b.Property<Guid>("DocumentId") | |||
| .HasColumnType("uniqueidentifier"); | |||
| b.HasKey("Id"); | |||
| @@ -12,14 +12,16 @@ namespace Diligent.WebAPI.Host.Controllers.V1 | |||
| private readonly ICategoryService _categoryService; | |||
| private readonly ITagService _tagService; | |||
| private readonly IFileEntityService _fileEntityService; | |||
| private readonly IDocumentService _documentService; | |||
| private readonly Microsoft.AspNetCore.Hosting.IHostingEnvironment _hostingEnvironment; | |||
| public FilesController(Microsoft.AspNetCore.Hosting.IHostingEnvironment hostingEnvironment, IFileEntityService fileEntityService, ICategoryService categoryService, ITagService tagService) | |||
| public FilesController(Microsoft.AspNetCore.Hosting.IHostingEnvironment hostingEnvironment, IFileEntityService fileEntityService, ICategoryService categoryService, ITagService tagService, IDocumentService documentService) | |||
| { | |||
| _hostingEnvironment = hostingEnvironment; | |||
| _fileEntityService = fileEntityService; | |||
| _categoryService = categoryService; | |||
| _tagService = tagService; | |||
| _documentService = documentService; | |||
| } | |||
| [HttpGet] | |||
| @@ -42,8 +44,9 @@ namespace Diligent.WebAPI.Host.Controllers.V1 | |||
| foreach (var id in request.TagsIds) | |||
| tags.Add(await _tagService.GetTagEntityById(id)); | |||
| var file = await _documentService.UploadDocument(request.FileToUpload); | |||
| await _fileEntityService.UploadPdfAsync(new FileEntity { CategoryId = request.CategoryId, Category = category, Tags = tags, Name = filePath, Extension = "pdf", Size = 100}); | |||
| await _fileEntityService.UploadPdfAsync(new FileEntity { CategoryId = request.CategoryId, DocumentId = file.stream_id, Category = category, Tags = tags}); | |||
| return Ok(); | |||
| } | |||
| } | |||