From fc17e89cc5a8e6191e1839c18aff2460b17a7d3e Mon Sep 17 00:00:00 2001 From: Ahmet Date: Thu, 28 May 2020 17:31:08 +0300 Subject: [PATCH] Blob database provider added --- .../Volo/Abp/BlobStoring/Database/Blob.cs | 26 ++++++ .../Abp/BlobStoring/Database/Container.cs | 11 +++ .../Database/DatabaseBlobProvider.cs | 87 +++++++++++++++++++ .../BlobStoring/Database/IBlobRepository.cs | 17 ++++ .../Database/IContainerRepository.cs | 14 +++ 5 files changed, 155 insertions(+) create mode 100644 modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain/Volo/Abp/BlobStoring/Database/Blob.cs create mode 100644 modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain/Volo/Abp/BlobStoring/Database/Container.cs create mode 100644 modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain/Volo/Abp/BlobStoring/Database/DatabaseBlobProvider.cs create mode 100644 modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain/Volo/Abp/BlobStoring/Database/IBlobRepository.cs create mode 100644 modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain/Volo/Abp/BlobStoring/Database/IContainerRepository.cs diff --git a/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain/Volo/Abp/BlobStoring/Database/Blob.cs b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain/Volo/Abp/BlobStoring/Database/Blob.cs new file mode 100644 index 0000000000..121352d6e8 --- /dev/null +++ b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain/Volo/Abp/BlobStoring/Database/Blob.cs @@ -0,0 +1,26 @@ +using System; +using Volo.Abp.Data; +using Volo.Abp.Domain.Entities; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.BlobStoring.Database +{ + public class Blob : AggregateRoot, IMultiTenant + { + public Guid ContainerId { get; set; } + + public Guid? TenantId { get; } + + public string Name { get; set; } + + public byte[] Content { get; set; } + + public Blob(Guid id, Guid containerId, string name, byte[] content, Guid? tenantId) : base(id) + { + ContainerId = containerId; + Name = name; + Content = content; + TenantId = tenantId; + } + } +} \ No newline at end of file diff --git a/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain/Volo/Abp/BlobStoring/Database/Container.cs b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain/Volo/Abp/BlobStoring/Database/Container.cs new file mode 100644 index 0000000000..8779a2778e --- /dev/null +++ b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain/Volo/Abp/BlobStoring/Database/Container.cs @@ -0,0 +1,11 @@ +using System; +using Volo.Abp.Domain.Entities; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.BlobStoring.Database +{ + public class Container : AggregateRoot, IMultiTenant + { + public Guid? TenantId { get; } + } +} \ No newline at end of file diff --git a/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain/Volo/Abp/BlobStoring/Database/DatabaseBlobProvider.cs b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain/Volo/Abp/BlobStoring/Database/DatabaseBlobProvider.cs new file mode 100644 index 0000000000..6ca4692d10 --- /dev/null +++ b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain/Volo/Abp/BlobStoring/Database/DatabaseBlobProvider.cs @@ -0,0 +1,87 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.BlobStoring.Database +{ + public class DatabaseBlobProvider : BlobProviderBase, ITransientDependency + { + protected IBlobRepository BlobRepository { get; } + protected IContainerRepository ContainerRepository { get; } + + public DatabaseBlobProvider(IBlobRepository blobRepository, IContainerRepository containerRepository) + { + BlobRepository = blobRepository; + ContainerRepository = containerRepository; + } + + public override async Task SaveAsync(BlobProviderSaveArgs args) + { + var container = await ContainerRepository.GetContainerAsync(args.ContainerName); + + var blob = await BlobRepository.FindAsync(container.Id, args.BlobName, args.TenantId, args.CancellationToken); + + var content = await args.BlobStream.GetAllBytesAsync(args.CancellationToken); + + if (blob != null) + { + if (!args.OverrideExisting) + { + throw new BlobAlreadyExistsException($"Saving BLOB '{args.BlobName}' does already exists in the container '{args.ContainerName}'! Set {nameof(args.OverrideExisting)} if it should be overwritten."); + } + + blob.Content = content; + await BlobRepository.UpdateAsync(blob); + } + else + { + blob = new Blob(Guid.NewGuid(), container.Id, args.BlobName, content, args.TenantId); + await BlobRepository.InsertAsync(blob); + } + } + + public override async Task DeleteAsync(BlobProviderDeleteArgs args) + { + var container = await ContainerRepository.FindContainerAsync(args.ContainerName); + + if (container == null) + { + return false; + } + + return await BlobRepository.DeleteAsync(container.Id, args.BlobName, args.TenantId, args.CancellationToken); + } + + public override async Task ExistsAsync(BlobProviderExistsArgs args) + { + var container = await ContainerRepository.FindContainerAsync(args.ContainerName); + + if (container == null) + { + return false; + } + + return await BlobRepository.ExistsAsync(container.Id, args.BlobName, args.TenantId, args.CancellationToken); + } + + public override async Task GetOrNullAsync(BlobProviderGetArgs args) + { + var container = await ContainerRepository.FindContainerAsync(args.ContainerName); + + if (container == null) + { + return null; + } + + var blob = await BlobRepository.FindAsync(container.Id, args.BlobName, args.TenantId, args.CancellationToken); + + if (blob == null) + { + return null; + } + + return new MemoryStream(blob.Content); + } + } +} \ No newline at end of file diff --git a/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain/Volo/Abp/BlobStoring/Database/IBlobRepository.cs b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain/Volo/Abp/BlobStoring/Database/IBlobRepository.cs new file mode 100644 index 0000000000..af0f237da2 --- /dev/null +++ b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain/Volo/Abp/BlobStoring/Database/IBlobRepository.cs @@ -0,0 +1,17 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using JetBrains.Annotations; +using Volo.Abp.Domain.Repositories; + +namespace Volo.Abp.BlobStoring.Database +{ + public interface IBlobRepository : IBasicRepository + { + Task FindAsync(Guid containerId, [NotNull] string blobName, Guid? tenantId = null, CancellationToken cancellationToken = default); + + Task ExistsAsync(Guid containerId, [NotNull] string blobName, Guid? tenantId = null, CancellationToken cancellationToken = default); + + Task DeleteAsync(Guid containerId, [NotNull] string blobName, Guid? tenantId = null, CancellationToken cancellationToken = default); + } +} \ No newline at end of file diff --git a/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain/Volo/Abp/BlobStoring/Database/IContainerRepository.cs b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain/Volo/Abp/BlobStoring/Database/IContainerRepository.cs new file mode 100644 index 0000000000..8db5dcd148 --- /dev/null +++ b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain/Volo/Abp/BlobStoring/Database/IContainerRepository.cs @@ -0,0 +1,14 @@ +using System; +using System.Threading.Tasks; +using JetBrains.Annotations; +using Volo.Abp.Domain.Repositories; + +namespace Volo.Abp.BlobStoring.Database +{ + public interface IContainerRepository : IBasicRepository + { + Task GetContainerAsync([NotNull] string name); + + Task FindContainerAsync([NotNull] string name); + } +} \ No newline at end of file