using Dapper; using Microsoft.Data.Sqlite; using Microsoft.Extensions.Options; namespace CrupestApi.Commons.Crud; public class CrudService { protected readonly TableInfo _table; protected readonly IOptionsSnapshot _crupestApiOptions; private readonly ILogger> _logger; public CrudService(ServiceProvider services) { _table = new TableInfo(typeof(TEntity)); _crupestApiOptions = services.GetRequiredService>(); _logger = services.GetRequiredService>>(); } public virtual string GetDbConnectionString() { var fileName = Path.Combine(_crupestApiOptions.Value.DataDir, "crupest-api.db"); return new SqliteConnectionStringBuilder() { DataSource = fileName, Mode = SqliteOpenMode.ReadWriteCreate }.ToString(); } public async Task CreateDbConnection() { var connection = new SqliteConnection(GetDbConnectionString()); await connection.OpenAsync(); return connection; } public virtual async Task DoInitializeDatabase(SqliteConnection connection) { await using var transaction = await connection.BeginTransactionAsync(); await connection.ExecuteAsync(_table.GenerateCreateTableSql(), transaction: transaction); await transaction.CommitAsync(); } public virtual async Task EnsureDatabase() { var connection = await CreateDbConnection(); var exist = await _table.CheckExistence(connection); if (!exist) { await DoInitializeDatabase(connection); } return connection; } public virtual async Task> QueryAsync(WhereClause? where = null, OrderByClause? orderBy = null, int? skip = null, int? limit = null) { var connection = await EnsureDatabase(); DynamicParameters parameters; var sql = _table.GenerateSelectSql(where, orderBy, skip, limit, out parameters); return await connection.QueryAsync(sql, parameters); } public virtual async Task InsertAsync(InsertClause insert) { var connection = await EnsureDatabase(); DynamicParameters parameters; var sql = _table.GenerateInsertSql(insert, out parameters); return await connection.ExecuteAsync(sql, parameters); } public virtual async Task UpdateAsync(WhereClause? where, UpdateClause update) { var connection = await EnsureDatabase(); DynamicParameters parameters; var sql = _table.GenerateUpdateSql(where, update, out parameters); return await connection.ExecuteAsync(sql, parameters); } public virtual async Task DeleteAsync(WhereClause? where) { var connection = await EnsureDatabase(); DynamicParameters parameters; var sql = _table.GenerateDeleteSql(where, out parameters); return await connection.ExecuteAsync(sql, parameters); } }