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; protected readonly ILogger> _logger; public CrudService(IOptionsSnapshot crupestApiOptions, ILogger> logger) { _table = new TableInfo(typeof(TEntity)); _crupestApiOptions = crupestApiOptions; _logger = logger; } 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); } }