using System.Data; using System.Text.Json; using Dapper; namespace CrupestApi.Commons.Crud; public class CrudService : IDisposable where TEntity : class { protected readonly TableInfo _table; protected readonly string? _connectionName; protected readonly IDbConnection _dbConnection; protected readonly EntityJsonHelper _jsonHelper; private readonly ILogger> _logger; public CrudService(ITableInfoFactory tableInfoFactory, IDbConnectionFactory dbConnectionFactory, EntityJsonHelper jsonHelper, ILoggerFactory loggerFactory) { _connectionName = GetConnectionName(); _table = tableInfoFactory.Get(typeof(TEntity)); _dbConnection = dbConnectionFactory.Get(_connectionName); _jsonHelper = jsonHelper; _logger = loggerFactory.CreateLogger>(); CheckDatabase(_dbConnection); } protected virtual string GetConnectionName() { return typeof(TEntity).Name; } public EntityJsonHelper JsonHelper => _jsonHelper; protected virtual void CheckDatabase(IDbConnection dbConnection) { if (!_table.CheckExistence(dbConnection)) { DoInitializeDatabase(dbConnection); } } protected virtual void DoInitializeDatabase(IDbConnection connection) { using var transaction = connection.BeginTransaction(); connection.Execute(_table.GenerateCreateTableSql(), transaction: transaction); transaction.Commit(); } public void Dispose() { _dbConnection.Dispose(); } public List GetAll() { var result = _table.Select(_dbConnection, null); return result; } public TEntity GetByKey(object key) { var result = _table.Select(_dbConnection, null, WhereClause.Create().Eq(_table.KeyColumn.ColumnName, key)); return result.Single(); } public string Create(JsonElement jsonElement) { var insertClauses = _jsonHelper.ConvertJsonElementToInsertClauses(jsonElement); var key = _table.Insert(_dbConnection, insertClauses); return (string)key; } public void UpdateByKey(object key, JsonElement jsonElement) { var updateClauses = _jsonHelper.ConvertJsonElementToUpdateClause(jsonElement); _table.Update(_dbConnection, WhereClause.Create().Eq(_table.KeyColumn.ColumnName, key), updateClauses); } public void DeleteByKey(object key) { _table.Delete(_dbConnection, WhereClause.Create().Eq(_table.KeyColumn.ColumnName, key)); } }