|
|
|
|
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<ConstraintNameType, List<string>> Constraints { get; }
|
|
|
|
|
|
|
|
|
|
public async Task Execute(string commandText)
|
|
|
|
|
{
|
|
|
|
|
await Storage.Open<AdHocSchemaEntity>().Select(new SchemaStorageArgs(new StorageOperation { CommandText = commandText }, typeof(SqlDataConnection), ConnectionString));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<AdHocSchemaEntity?> Select(string commandText)
|
|
|
|
|
{
|
|
|
|
|
return await Storage.Open<AdHocSchemaEntity>().Select(new SchemaStorageArgs(new StorageOperation { CommandText = commandText }, typeof(SqlDataConnection), ConnectionString));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<IDataReader?> OpenReader(IStorageOperation operation)
|
|
|
|
|
{
|
|
|
|
|
var readers = await Storage.Open<AdHocSchemaEntity>().OpenReaders(new SchemaStorageArgs(operation, typeof(SqlDataConnection), ConnectionString));
|
|
|
|
|
|
|
|
|
|
return readers[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void AddConstraint(ConstraintNameType type, string name)
|
|
|
|
|
{
|
|
|
|
|
if (!Constraints.TryGetValue(type, out List<string>? existing))
|
|
|
|
|
{
|
|
|
|
|
existing = new List<string>();
|
|
|
|
|
|
|
|
|
|
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"
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|