|
|
|
|
using Connected.Entities.Annotations;
|
|
|
|
|
using Connected.Entities.Storage;
|
|
|
|
|
using System.Collections.Concurrent;
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
|
|
|
|
|
namespace Connected.Data.Update;
|
|
|
|
|
|
|
|
|
|
internal sealed class UpdateCommandBuilder : CommandBuilder
|
|
|
|
|
{
|
|
|
|
|
private static readonly ConcurrentDictionary<string, StorageOperation> _cache;
|
|
|
|
|
|
|
|
|
|
static UpdateCommandBuilder()
|
|
|
|
|
{
|
|
|
|
|
_cache = new();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static ConcurrentDictionary<string, StorageOperation> Cache => _cache;
|
|
|
|
|
private bool SupportsConcurrency { get; set; }
|
|
|
|
|
protected override bool TryGetExisting(out StorageOperation? result)
|
|
|
|
|
{
|
|
|
|
|
return Cache.TryGetValue(Entity.GetType().FullName, out result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override StorageOperation OnBuild()
|
|
|
|
|
{
|
|
|
|
|
WriteLine($"UPDATE [{Schema.Schema}].[{Schema.Name}] SET");
|
|
|
|
|
|
|
|
|
|
WriteAssignments();
|
|
|
|
|
WriteWhere();
|
|
|
|
|
|
|
|
|
|
Trim();
|
|
|
|
|
Write(';');
|
|
|
|
|
|
|
|
|
|
var result = new StorageOperation { CommandText = CommandText, Concurrency = SupportsConcurrency ? DataConcurrencyMode.Enabled : DataConcurrencyMode.Disabled };
|
|
|
|
|
|
|
|
|
|
foreach (var parameter in Parameters)
|
|
|
|
|
result.AddParameter(parameter);
|
|
|
|
|
|
|
|
|
|
Cache.TryAdd(Entity.GetType().FullName, result);
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void WriteAssignments()
|
|
|
|
|
{
|
|
|
|
|
foreach (var property in Properties)
|
|
|
|
|
{
|
|
|
|
|
if (property.GetCustomAttribute<PrimaryKeyAttribute>() is not null || IsVersion(property))
|
|
|
|
|
{
|
|
|
|
|
if (IsVersion(property))
|
|
|
|
|
SupportsConcurrency = true;
|
|
|
|
|
|
|
|
|
|
WhereProperties.Add(property);
|
|
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var parameter = CreateParameter(property);
|
|
|
|
|
|
|
|
|
|
WriteLine($"{ColumnName(property)} = {parameter.Name},");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Trim();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void WriteWhere()
|
|
|
|
|
{
|
|
|
|
|
WriteLine(string.Empty);
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < WhereProperties.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
var property = WhereProperties[i];
|
|
|
|
|
var parameter = CreateParameter(property);
|
|
|
|
|
|
|
|
|
|
if (i == 0)
|
|
|
|
|
WriteLine($" WHERE {ColumnName(property)} = {parameter.Name}");
|
|
|
|
|
else
|
|
|
|
|
WriteLine($" AND {ColumnName(property)} = {parameter.Name}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|