using Connected.Data.Sql; using Connected.Entities.Storage; using System.Data; namespace Connected.Data.Schema.Sql; internal class SchemaExecutionContext { private ExistingSchema _existingSchema; public SchemaExecutionContext(IStorageProvider storage, ISchema schema, string connectionString) { Storage = storage; Schema = schema; ConnectionString = connectionString; Constraints = new(); } public ExistingSchema ExistingSchema { get => _existingSchema; set { _existingSchema = value; if (_existingSchema is null) return; foreach (var index in _existingSchema.Descriptor.Constraints) { switch (index.ConstraintType) { case ConstraintType.Default: AddConstraint(ConstraintNameType.Default, index.Name); break; case ConstraintType.PrimaryKey: AddConstraint(ConstraintNameType.PrimaryKey, index.Name); break; case ConstraintType.Unique: AddConstraint(ConstraintNameType.Index, index.Name); break; } } } } public IStorageProvider Storage { get; } public ISchema Schema { get; } private string ConnectionString { get; } public Dictionary> Constraints { get; } public async Task Execute(string commandText) { await Storage.Open().Select(new SchemaStorageArgs(new StorageOperation { CommandText = commandText }, typeof(SqlDataConnection), ConnectionString)); } public async Task Select(string commandText) { return await Storage.Open().Select(new SchemaStorageArgs(new StorageOperation { CommandText = commandText }, typeof(SqlDataConnection), ConnectionString)); } public async Task OpenReader(IStorageOperation operation) { var readers = await Storage.Open().OpenReaders(new SchemaStorageArgs(operation, typeof(SqlDataConnection), ConnectionString)); return readers[0]; } private void AddConstraint(ConstraintNameType type, string name) { if (!Constraints.TryGetValue(type, out List? existing)) { existing = new List(); Constraints.Add(type, existing); } if (ConstraintNameExists(name)) existing.Add(name); } public string GenerateConstraintName(string schema, string tableName, ConstraintNameType type) { var index = 0; while (true) { var value = $"{ConstraintPrefix(type)}_{schema.ToLowerInvariant()}_{tableName}"; if (index > 0) value = $"{value}_{index}"; if (!ConstraintNameExists(value)) { AddConstraint(type, value); return value; } index++; } } private bool ConstraintNameExists(string value) { foreach (var key in Constraints) { foreach (var item in key.Value) { if (item.Contains(value, StringComparison.OrdinalIgnoreCase)) return true; } } return false; } private static string ConstraintPrefix(ConstraintNameType type) { return type switch { ConstraintNameType.Default => "DF", ConstraintNameType.PrimaryKey => "PK", ConstraintNameType.Index => "IX", _ => "IX" }; } }