using System.Data; using Dapper; using Microsoft.Extensions.Configuration; using Npgsql; using UserOfTheDayBot.Model; namespace UserOfTheDayBot.Data; public interface IUserOfTheDayRepository { Task RecordUserOfTheDayAsync(long chatId, long userId, DateTime date, UserOfTheDayType type); Task IsUserOfTheDaySelectedAsync(long chatId, DateTime date, UserOfTheDayType type); Task IsUserAlreadySelectedAsync(long chatId, DateTime date, long userId); Task> GetUserStatisticsAsync(long chatId); } public class UserOfTheDayRepository : IUserOfTheDayRepository { private readonly string _connectionString; public UserOfTheDayRepository(IConfiguration configuration) { _connectionString = configuration["DatabaseSettings:ConnectionString"]; } public async Task RecordUserOfTheDayAsync(long chatId, long userId, DateTime date, UserOfTheDayType type) { using (IDbConnection db = new NpgsqlConnection(_connectionString)) { string query = "INSERT INTO user_of_the_day (chat_id, user_id, date, type) VALUES (@ChatId, @UserId, @Date, @Type)"; await db.ExecuteAsync(query, new { ChatId = chatId, UserId = userId, Date = date, Type = type }); } } public async Task IsUserOfTheDaySelectedAsync(long chatId, DateTime date, UserOfTheDayType type) { using (IDbConnection db = new NpgsqlConnection(_connectionString)) { string query = "SELECT CAST(CASE WHEN EXISTS (SELECT COUNT(1) FROM user_of_the_day WHERE chat_id = @ChatId AND date = @Date AND type = @Type) THEN 1 ELSE 0 END as BIT)"; var res = await db.ExecuteScalarAsync(query, new { ChatId = chatId, Date = date, Type = type }); Console.WriteLine($"{chatId} : {type} : {res}"); return res; } } public async Task IsUserAlreadySelectedAsync(long chatId, DateTime date, long userId) { using (IDbConnection db = new NpgsqlConnection(_connectionString)) { string query = "SELECT COUNT(1) FROM user_of_the_day WHERE chat_id = @ChatId AND date = @Date AND user_id = @UserId"; return await db.ExecuteScalarAsync(query, new { ChatId = chatId, Date = date, UserId = userId }); } } public async Task> GetUserStatisticsAsync(long chatId) { using (IDbConnection db = new NpgsqlConnection(_connectionString)) { string query = @"SELECT u.user_id, u.user_name, SUM(CASE WHEN ud.type = 0 THEN 1 ELSE 0 END) AS user_of_the_day_count, SUM(CASE WHEN ud.type = 1 THEN 1 ELSE 0 END) AS loser_of_the_day_count FROM user_of_the_day ud JOIN users u ON ud.user_id = u.user_id AND ud.chat_id = u.chat_id WHERE ud.chat_id = @ChatId GROUP BY u.user_id, u.user_name"; var results = await db.QueryAsync<(long userId, string userName, int userOfTheDayCount, int loserOfTheDayCount)>(query, new { ChatId = chatId }); return results.ToDictionary( row => (row.userId, row.userName), row => (row.userOfTheDayCount, row.loserOfTheDayCount) ); } } }