Skip to content

Commit

Permalink
Initial implementation of the pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
tsutomi committed Nov 11, 2022
1 parent 35bbb68 commit 381bad3
Show file tree
Hide file tree
Showing 40 changed files with 1,687 additions and 0 deletions.
39 changes: 39 additions & 0 deletions Deveel.Repository.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{2860FD4D-510F-43C8-870E-5559B90D0CAD}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{50434E05-0F21-4871-AFB3-A483CEE4A300}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Deveel.Repository.Core", "src\Deveel.Repository.Core\Deveel.Repository.Core.csproj", "{EA6BBF15-2CFB-428F-80CB-9CEC546900CD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Deveel.Repository.MongoDb", "src\Deveel.Repository.MongoDb\Deveel.Repository.MongoDb.csproj", "{E321F743-40CD-4599-B70C-FE9694A845BE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{EA6BBF15-2CFB-428F-80CB-9CEC546900CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EA6BBF15-2CFB-428F-80CB-9CEC546900CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EA6BBF15-2CFB-428F-80CB-9CEC546900CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EA6BBF15-2CFB-428F-80CB-9CEC546900CD}.Release|Any CPU.Build.0 = Release|Any CPU
{E321F743-40CD-4599-B70C-FE9694A845BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E321F743-40CD-4599-B70C-FE9694A845BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E321F743-40CD-4599-B70C-FE9694A845BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E321F743-40CD-4599-B70C-FE9694A845BE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{EA6BBF15-2CFB-428F-80CB-9CEC546900CD} = {2860FD4D-510F-43C8-870E-5559B90D0CAD}
{E321F743-40CD-4599-B70C-FE9694A845BE} = {2860FD4D-510F-43C8-870E-5559B90D0CAD}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {01FD9B16-84B3-4D99-80C1-11B2F3D65B56}
EndGlobalSection
EndGlobal
43 changes: 43 additions & 0 deletions EULA.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
## End-User License Agreement (EULA) of *Deveel Framework*

This End-User License Agreement ("EULA") is a legal agreement between you and *Deveel*.

This EULA agreement governs your acquisition and use of our *Deveel Framework* software ("Software") directly from *Deveel* or indirectly through a *Deveel* authorized reseller or distributor (a "Reseller").

Please read this EULA agreement carefully before completing the installation process and using the *Deveel Framework* software. It provides a license to use the *Deveel Framework* software and contains warranty information and liability disclaimers.

If you register for a free trial of the *Deveel Framework* software, this EULA agreement will also govern that trial. By clicking "accept" or installing and/or using the *Deveel Framework* software, you are confirming your acceptance of the Software and agreeing to become bound by the terms of this EULA agreement.

If you are entering into this EULA agreement on behalf of a company or other legal entity, you represent that you have the authority to bind such entity and its affiliates to these terms and conditions. If you do not have such authority or if you do not agree with the terms and conditions of this EULA agreement, do not install or use the Software, and you must not accept this EULA agreement.

This EULA agreement shall apply only to the Software supplied by *Deveel* herewith regardless of whether other software is referred to or described herein. The terms also apply to any *Deveel* updates, supplements, Internet-based services, and support services for the Software, unless other terms accompany those items on delivery. If so, those terms apply.

### License Grant

*Deveel* hereby grants you a personal, non-transferable, non-exclusive licence to use the *Deveel Framework* software on your devices in accordance with the terms of this EULA agreement.

You are permitted to load the *Deveel Framework* software (for example a PC, laptop, mobile or tablet) under your control. You are responsible for ensuring your device meets the minimum requirements of the *Deveel Framework* software.

You are not permitted to:

* Edit, alter, modify, adapt, translate or otherwise change the whole or any part of the Software nor permit the whole or any part of the Software to be combined with or become incorporated in any other software, nor decompile, disassemble or reverse engineer the Software or attempt to do any such things
* Reproduce, copy, distribute, resell or otherwise use the Software for any commercial purpose
* Allow any third party to use the Software on behalf of or for the benefit of any third party
* Use the Software in any way which breaches any applicable local, national or international law
* use the Software for any purpose that *Deveel* considers is a breach of this EULA agreement

### Intellectual Property and Ownership

*Deveel* shall at all times retain ownership of the Software as originally downloaded by you and all subsequent downloads of the Software by you. The Software (and the copyright, and other intellectual property rights of whatever nature in the Software, including any modifications made thereto) are and shall remain the property of *Deveel*.

*Deveel* reserves the right to grant licences to use the Software to third parties.

### Termination

This EULA agreement is effective from the date you first use the Software and shall continue until terminated. You may terminate it at any time upon written notice to *Deveel*.

It will also terminate immediately if you fail to comply with any term of this EULA agreement. Upon such termination, the licenses granted by this EULA agreement will immediately terminate and you agree to stop all access and use of the Software. The provisions that by their nature continue and survive will survive any termination of this EULA agreement.

### Governing Law

This EULA agreement, and any dispute arising out of or in connection with this EULA agreement, shall be governed by and construed in accordance with the laws of **Norway**.
Binary file added deveel-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
38 changes: 38 additions & 0 deletions src/Deveel.Repository.Core/Deveel.Repository.Core.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>Deveel</RootNamespace>
<VersionPrefix>1.0.0</VersionPrefix>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Authors>Antonello Provenzano</Authors>
<Company>Deveel AS</Company>
<Copyright>(C) 2022 Deveel</Copyright>
<PackageProjectUrl>https://github.com/deveel/deveel.data.repository</PackageProjectUrl>
<RepositoryUrl>https://github.com/deveel/deveel.data.repository</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>data core framework repository</PackageTags>
<Description>Abstractions for the definition of repositories of data</Description>
<PackageLicenseFile>EULA.md</PackageLicenseFile>
<PackageIcon>deveel-logo.png</PackageIcon>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Deveel.Model.Core" Version="1.1.0-3428745760" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0" />
</ItemGroup>

<ItemGroup>
<None Include="..\..\deveel-logo.png">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
<None Include="..\..\EULA.md">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
</ItemGroup>
</Project>
28 changes: 28 additions & 0 deletions src/Deveel.Repository.Core/Repository/ExpressionFieldRef.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System;
using System.Linq.Expressions;

namespace Deveel.Data {
/// <summary>
/// References a expr of an entity through a selection expression
/// </summary>
/// <typeparam name="TEntity">The type of the entity defining the expr to be selected</typeparam>
public sealed class ExpressionFieldRef<TEntity> : IFieldRef where TEntity : class, IEntity {
/// <summary>
/// Constucts the reference with the expression to select
/// the expr from the entity
/// </summary>
/// <param name="expr">The expression that is used to select the expr</param>
/// <exception cref="ArgumentNullException">
/// Thrown if the expression is empty
/// </exception>
public ExpressionFieldRef(Expression<Func<TEntity, object>> expr) {
Expression = expr ?? throw new ArgumentNullException(nameof(expr));
}

/// <summary>
/// Gets the expression used to select a field from the
/// underlying entity
/// </summary>
public Expression<Func<TEntity, object>> Expression { get; }
}
}
20 changes: 20 additions & 0 deletions src/Deveel.Repository.Core/Repository/ExpressionQueryFilter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;
using System.Linq.Expressions;

namespace Deveel.Data {
/// <summary>
/// An implementation of a query expr that uses a lambda expression
/// </summary>
/// <typeparam name="TEntity">The type of entity to construct
/// the expr</typeparam>
public sealed class ExpressionQueryFilter<TEntity> : IQueryFilter where TEntity : class, IEntity {
public ExpressionQueryFilter(Expression<Func<TEntity, bool>> expr) {
Expression = expr ?? throw new ArgumentNullException(nameof(expr));
}

/// <summary>
/// Gets the filter expression
/// </summary>
public Expression<Func<TEntity, bool>> Expression { get; }
}
}
84 changes: 84 additions & 0 deletions src/Deveel.Repository.Core/Repository/FacadeRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using System;

using Deveel.Data;
using Deveel.States;

using static System.Formats.Asn1.AsnWriter;

namespace Deveel.Repository {
class FacadeRepository<TEntity, TFacade> : IRepository<TFacade>
where TEntity : class, IEntity, TFacade
where TFacade : class, IEntity {
private readonly IRepository<TEntity> repository;

public FacadeRepository(IRepository<TEntity> repository) {
this.repository = repository;
}

public bool SupportsPaging => repository.SupportsPaging;

public bool SupportsFilters => repository.SupportsFilters;

private TEntity Assert(TFacade entity) {
if (!(entity is TEntity other))
throw new ArgumentException($"The object of type '{typeof(TFacade)}' cannot be converted to '{typeof(TEntity)}'");

return other;
}

private TEntity Assert(object entity) {
if (!(entity is TEntity other))
throw new ArgumentException($"The object cannot be converted to '{typeof(TEntity)}'");

return other;
}

public Task<string> CreateAsync(TFacade entity, CancellationToken cancellationToken)
=> repository.CreateAsync(Assert(entity), cancellationToken);

public Task<string> CreateAsync(IDataTransaction session, TFacade entity, CancellationToken cancellationToken)
=> repository.CreateAsync(session, Assert(entity), cancellationToken);

public Task<string> CreateAsync(IEntity entity, CancellationToken cancellationToken)
=> repository.CreateAsync(Assert(entity), cancellationToken);

public Task<string> CreateAsync(IDataTransaction session, IEntity entity, CancellationToken cancellationToken)
=> repository.CreateAsync(session, Assert(entity), cancellationToken);

public Task<bool> DeleteAsync(TFacade entity, CancellationToken cancellationToken)
=> repository.DeleteAsync(Assert(entity), cancellationToken);

public Task<bool> DeleteAsync(IDataTransaction session, TFacade entity, CancellationToken cancellationToken)
=> repository.DeleteAsync(session, Assert(entity), cancellationToken);

public Task<bool> DeleteAsync(IEntity entity, CancellationToken cancellationToken)
=> repository.DeleteAsync(Assert(entity), cancellationToken);

public Task<bool> DeleteAsync(IDataTransaction session, IEntity entity, CancellationToken cancellationToken)
=> repository.DeleteAsync(session, Assert(entity), cancellationToken);

public async Task<TFacade> FindByIdAsync(string id, CancellationToken cancellationToken)
=> await repository.FindByIdAsync(id, cancellationToken);

public Task<bool> UpdateAsync(TFacade entity, CancellationToken cancellationToken)
=> repository.UpdateAsync(Assert(entity), cancellationToken);

public Task<bool> UpdateAsync(IDataTransaction session, TFacade entity, CancellationToken cancellationToken)
=> repository.UpdateAsync(session, Assert(entity), cancellationToken);

public Task<bool> UpdateAsync(IEntity entity, CancellationToken cancellationToken)
=> repository.UpdateAsync(Assert(entity), cancellationToken);

public Task<bool> UpdateAsync(IDataTransaction session, IEntity entity, CancellationToken cancellationToken)
=> repository.UpdateAsync(session, Assert(entity), cancellationToken);

async Task<IEntity> IRepository.FindByIdAsync(string id, CancellationToken cancellationToken)
=> await repository.FindByIdAsync(id, cancellationToken);

async Task<PaginatedResult> IRepository.GetPageAsync(PageRequest page, CancellationToken cancellationToken)
=> await repository.GetPageAsync(page, cancellationToken);

public Task<PaginatedResult<TFacade>> GetPageAsync(PageRequest<TFacade> request, CancellationToken cancellationToken = default)
=> throw new NotImplementedException();
}
}
19 changes: 19 additions & 0 deletions src/Deveel.Repository.Core/Repository/FacadeRepositoryProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;

using Deveel.Data;

namespace Deveel.Repository {
class FacadeRepositoryProvider<TEntity, TFacade> : IRepositoryProvider<TFacade>
where TEntity : class, TFacade, IEntity
where TFacade : class, IEntity {
private readonly IRepositoryProvider<TEntity> provider;

public FacadeRepositoryProvider(IRepositoryProvider<TEntity> provider) {
this.provider = provider;
}

public IRepository<TFacade> GetRepository(string tenantId) => (IRepository<TFacade>) provider.GetRepository(tenantId);

IRepository IRepositoryProvider.GetRepository(string tenantId) => provider.GetRepository(tenantId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System;

using Deveel.Data;

namespace Deveel.Repository {
public interface IConvertibleQueryFilter : IQueryFilter {
IQueryFilter ConvertFor<TEntity>();
}
}
14 changes: 14 additions & 0 deletions src/Deveel.Repository.Core/Repository/IDataTransaction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;

namespace Deveel.Data {
/// <summary>
/// Represents a transaction provided by the underlying
/// storage of the repository, to isolate operations
/// of access to the data
/// </summary>
public interface IDataTransaction : IDisposable {
Task CommitAsync(CancellationToken cancellationToken = default);

Task RollbackAsync(CancellationToken cancellationToken = default);
}
}
20 changes: 20 additions & 0 deletions src/Deveel.Repository.Core/Repository/IDataTransactionFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;

namespace Deveel.Data {
/// <summary>
/// A factory that provides instances of transactions
/// used to isolate the access to data layers of an underlying storage
/// </summary>
public interface IDataTransactionFactory {
/// <summary>
/// Creates a new stransaction and starts it
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns>
/// Returns a new instance of <see cref="IDataTransaction"/> that
/// can be used in a <see cref="IRepository"/> to isolate
/// the access to the data of an underlying storage
/// </returns>
Task<IDataTransaction> CreateTransactionAsync(CancellationToken cancellationToken);
}
}
10 changes: 10 additions & 0 deletions src/Deveel.Repository.Core/Repository/IFieldRef.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System;

namespace Deveel.Data {
/// <summary>
/// A marker interface that is implemented by objects referencing
/// a field of an entity
/// </summary>
public interface IFieldRef {
}
}
10 changes: 10 additions & 0 deletions src/Deveel.Repository.Core/Repository/IQueryFilter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System;

namespace Deveel.Data {
/// <summary>
/// A marker interface that is implemented by objects
/// representing filters of a query to a repository
/// </summary>
public interface IQueryFilter {
}
}
9 changes: 9 additions & 0 deletions src/Deveel.Repository.Core/Repository/IQueryableRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System;

using Deveel.Data;

namespace Deveel.Repository {
public interface IQueryableRepository<TEntity> : IRepository<TEntity> where TEntity : class, IEntity {
IQueryable<TEntity> AsQueryable();
}
}
Loading

0 comments on commit 381bad3

Please sign in to comment.