You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
138 lines
3.1 KiB
138 lines
3.1 KiB
using Connected.Entities;
|
|
using Connected.Entities.Storage;
|
|
using Connected.Interop;
|
|
using Connected.Middleware;
|
|
using Connected.ServiceModel;
|
|
using Connected.Services;
|
|
|
|
namespace Connected.Common.Numbering;
|
|
internal sealed class NumberingOps
|
|
{
|
|
public sealed class Calculate : ServiceFunction<NumberingCalculateArgs, string>
|
|
{
|
|
public Calculate(IMiddlewareService middleware)
|
|
{
|
|
Middleware = middleware;
|
|
}
|
|
|
|
private IMiddlewareService Middleware { get; }
|
|
|
|
protected override async Task<string?> OnInvoke()
|
|
{
|
|
foreach (var middleware in await Middleware.Query<INumberingProvider>())
|
|
{
|
|
if (await middleware.Invoke(Arguments) is string result && !string.IsNullOrEmpty(result))
|
|
return result;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public sealed class NextValue : ServiceFunction<NumberingCalculateArgs, string>
|
|
{
|
|
public NextValue(IStorageProvider storage, INumberingService numbering)
|
|
{
|
|
Storage = storage;
|
|
Numbering = numbering;
|
|
}
|
|
|
|
private IStorageProvider Storage { get; }
|
|
private INumberingService Numbering { get; }
|
|
|
|
protected override async Task<string?> OnInvoke()
|
|
{
|
|
var result = await Prepare();
|
|
|
|
await Storage.Open<Numbering>().Update(result, Arguments,
|
|
async () =>
|
|
{
|
|
result = await Prepare();
|
|
|
|
return result;
|
|
},
|
|
async (f) =>
|
|
{
|
|
await Task.CompletedTask;
|
|
|
|
return f;
|
|
});
|
|
|
|
return result.Value;
|
|
}
|
|
|
|
private async Task<Numbering> Prepare()
|
|
{
|
|
var current = await Numbering.Select(Arguments.AsArguments<NumberingSelectArgs>());
|
|
|
|
if (current is null)
|
|
{
|
|
var id = await TryInsert();
|
|
|
|
if (id == 0)
|
|
current = await Numbering.Select(Arguments.AsArguments<NumberingSelectArgs>());
|
|
else
|
|
current = await Numbering.Select(id);
|
|
}
|
|
|
|
if (current is null)
|
|
throw new NullReferenceException(nameof(INumbering));
|
|
|
|
var newValue = string.Empty;
|
|
|
|
if (TypeConversion.TryConvert(current.Value, out long existingValue))
|
|
newValue = existingValue++.ToString();
|
|
else
|
|
newValue = current.Value;
|
|
|
|
return (Numbering)current with { Value = newValue };
|
|
}
|
|
|
|
private async Task<int> TryInsert()
|
|
{
|
|
try
|
|
{
|
|
return (await Storage.Open<Numbering>().Update(Arguments.AsEntity<Numbering>(State.New))).Id;
|
|
}
|
|
catch
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
public sealed class SelectByEntity : ServiceFunction<NumberingSelectArgs, INumbering>
|
|
{
|
|
public SelectByEntity(IStorageProvider storage)
|
|
{
|
|
Storage = storage;
|
|
}
|
|
|
|
private IStorageProvider Storage { get; }
|
|
|
|
protected override async Task<INumbering?> OnInvoke()
|
|
{
|
|
return await (from e in Storage.Open<Numbering>()
|
|
where string.Equals(e.Entity, Arguments.Entity, StringComparison.OrdinalIgnoreCase)
|
|
select e).AsEntity();
|
|
}
|
|
}
|
|
|
|
public sealed class Select : ServiceFunction<PrimaryKeyArgs<int>, INumbering>
|
|
{
|
|
public Select(IStorageProvider storage)
|
|
{
|
|
Storage = storage;
|
|
}
|
|
|
|
private IStorageProvider Storage { get; }
|
|
|
|
protected override async Task<INumbering?> OnInvoke()
|
|
{
|
|
return await (from e in Storage.Open<Numbering>()
|
|
where e.Id == Arguments.Id
|
|
select e).AsEntity();
|
|
}
|
|
}
|
|
}
|