using Connected.Entities.Annotations; using Connected.Entities.Storage; using System.Collections.Concurrent; using System.Data; using System.Reflection; namespace Connected.Data.Update; internal class InsertCommandBuilder : CommandBuilder { private static readonly ConcurrentDictionary _cache; static InsertCommandBuilder() { _cache = new(); } private static ConcurrentDictionary Cache => _cache; private IStorageParameter PrimaryKeyParameter { get; set; } protected override StorageOperation OnBuild() { WriteLine($"INSERT [{Schema.Schema}].[{Schema.Name}] ("); WriteColumns(); WriteLine(")"); Write("VALUES ("); WriteValues(); WriteLine(");"); WriteOutput(); var result = new StorageOperation { CommandText = CommandText }; foreach (var parameter in Parameters) result.AddParameter(parameter); Cache.TryAdd(Entity.GetType().FullName, result); return result; } private void WriteOutput() { WriteLine($"SET {PrimaryKeyParameter.Name} = scope_identity();"); } private void WriteColumns() { foreach (var property in Properties) { if (property.GetCustomAttribute() is not null || IsVersion(property)) { if (IsVersion(property)) continue; PrimaryKeyParameter = CreateParameter(property, ParameterDirection.Output); continue; } CreateParameter(property); Write($"{ColumnName(property)}, "); } Trim(); } private void WriteValues() { foreach (var property in Properties) { if (property.GetCustomAttribute() is not null || IsVersion(property)) continue; Write($"@{ColumnName(property)}, "); } Trim(); } protected override bool TryGetExisting(out StorageOperation? result) { return Cache.TryGetValue(Entity.GetType().FullName, out result); } }