using CarCareTracker.External.Interfaces; using CarCareTracker.Models; using Npgsql; using System.Text.Json; namespace CarCareTracker.External.Implementations { public class PGApiKeyRecordDataAccess : IApiKeyRecordDataAccess { private NpgsqlDataSource pgDataSource; private readonly ILogger _logger; private static string tableName = "apikeyrecords"; public PGApiKeyRecordDataAccess(IConfiguration config, ILogger logger) { pgDataSource = NpgsqlDataSource.Create(config["POSTGRES_CONNECTION"]); _logger = logger; try { //create table if not exist. string initCMD = $"CREATE SCHEMA IF NOT EXISTS app; CREATE TABLE IF NOT EXISTS app.{tableName} (id INT GENERATED BY DEFAULT AS IDENTITY primary key, userId INT not null, apiKey TEXT not null, data jsonb not null)"; using (var ctext = pgDataSource.CreateCommand(initCMD)) { ctext.ExecuteNonQuery(); } } catch (Exception ex) { _logger.LogError(ex.Message); } } public List GetAPIKeyRecordsByUserId(int userId) { try { string cmd = $"SELECT data FROM app.{tableName} WHERE userId = @userId"; var results = new List(); using (var ctext = pgDataSource.CreateCommand(cmd)) { ctext.Parameters.AddWithValue("userId", userId); using (NpgsqlDataReader reader = ctext.ExecuteReader()) while (reader.Read()) { APIKey apiKeyRecord = JsonSerializer.Deserialize(reader["data"] as string); results.Add(apiKeyRecord); } } return results; } catch (Exception ex) { _logger.LogError(ex.Message); return new List(); } } public APIKey GetAPIKeyById(int apiKeyId) { try { string cmd = $"SELECT data FROM app.{tableName} WHERE id = @id"; var result = new APIKey(); using (var ctext = pgDataSource.CreateCommand(cmd)) { ctext.Parameters.AddWithValue("id", apiKeyId); using (NpgsqlDataReader reader = ctext.ExecuteReader()) while (reader.Read()) { APIKey apiKeyRecord = JsonSerializer.Deserialize(reader["data"] as string); result = apiKeyRecord; } } return result; } catch (Exception ex) { _logger.LogError(ex.Message); return new APIKey(); } } public APIKey GetAPIKeyByKey(string hashedKey) { try { string cmd = $"SELECT data FROM app.{tableName} WHERE apiKey = @apiKey"; var result = new APIKey(); using (var ctext = pgDataSource.CreateCommand(cmd)) { ctext.Parameters.AddWithValue("apiKey", hashedKey); using (NpgsqlDataReader reader = ctext.ExecuteReader()) while (reader.Read()) { APIKey apiKeyRecord = JsonSerializer.Deserialize(reader["data"] as string); result = apiKeyRecord; } } return result; } catch (Exception ex) { _logger.LogError(ex.Message); return new APIKey(); } } public bool DeleteAPIKeyById(int apiKeyId) { try { string cmd = $"DELETE FROM app.{tableName} WHERE id = @id"; using (var ctext = pgDataSource.CreateCommand(cmd)) { ctext.Parameters.AddWithValue("id", apiKeyId); return ctext.ExecuteNonQuery() > 0; } } catch (Exception ex) { _logger.LogError(ex.Message); return false; } } public bool SaveAPIKey(APIKey apiKey) { try { if (apiKey.Id == default) { string cmd = $"INSERT INTO app.{tableName} (userId, apiKey, data) VALUES(@userId, @apiKey, CAST(@data AS jsonb)) RETURNING id"; using (var ctext = pgDataSource.CreateCommand(cmd)) { ctext.Parameters.AddWithValue("userId", apiKey.UserId); ctext.Parameters.AddWithValue("apiKey", apiKey.Key); ctext.Parameters.AddWithValue("data", "{}"); apiKey.Id = Convert.ToInt32(ctext.ExecuteScalar()); //update json data if (apiKey.Id != default) { string cmdU = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id"; using (var ctextU = pgDataSource.CreateCommand(cmdU)) { var serializedData = JsonSerializer.Serialize(apiKey); ctextU.Parameters.AddWithValue("id", apiKey.Id); ctextU.Parameters.AddWithValue("data", serializedData); return ctextU.ExecuteNonQuery() > 0; } } return apiKey.Id != default; } } else { string cmd = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id"; using (var ctext = pgDataSource.CreateCommand(cmd)) { var serializedData = JsonSerializer.Serialize(apiKey); ctext.Parameters.AddWithValue("id", apiKey.Id); ctext.Parameters.AddWithValue("data", serializedData); return ctext.ExecuteNonQuery() > 0; } } } catch (Exception ex) { _logger.LogError(ex.Message); return false; } } public bool DeleteAllAPIKeysByUserId(int userId) { try { string cmd = $"DELETE FROM app.{tableName} WHERE userId = @id"; using (var ctext = pgDataSource.CreateCommand(cmd)) { ctext.Parameters.AddWithValue("id", userId); ctext.ExecuteNonQuery(); return true; } } catch (Exception ex) { _logger.LogError(ex.Message); return false; } } } }