diff --git a/DataAccessLayer/UserAccountRepository.cs b/DataAccessLayer/UserAccountRepository.cs index d8c9aa3..83c8779 100644 --- a/DataAccessLayer/UserAccountRepository.cs +++ b/DataAccessLayer/UserAccountRepository.cs @@ -18,239 +18,34 @@ namespace DataAccessLayer ?? throw new InvalidOperationException( "The connection string is not set in the environment variables." ); - - } public void Add(UserAccount userAccount) { - const string query = - @"INSERT INTO UserAccount (UserAccountID, Username, FirstName, LastName, Email, CreatedAt, UpdatedAt, DateOfBirth, Timer) - VALUES (@UserAccountID, @Username, @FirstName, @LastName, @Email, @CreatedAt, @UpdatedAt, @DateOfBirth, @Timer);"; - - using (var connection = new SqlConnection(_connectionString)) - using (var command = new SqlCommand(query, connection)) - { - _ = command.Parameters.AddWithValue( - "@UserAccountID", - userAccount.UserAccountID - ); - _ = command.Parameters.AddWithValue( - "@Username", - userAccount.Username - ); - _ = command.Parameters.AddWithValue( - "@FirstName", - userAccount.FirstName - ); - _ = command.Parameters.AddWithValue( - "@LastName", - userAccount.LastName - ); - _ = command.Parameters.AddWithValue( - "@Email", - userAccount.Email - ); - _ = command.Parameters.AddWithValue( - "@CreatedAt", - userAccount.CreatedAt - ); - _ = command.Parameters.AddWithValue( - "@UpdatedAt", - userAccount.UpdatedAt ?? (object)DBNull.Value - ); - _ = command.Parameters.AddWithValue( - "@DateOfBirth", - userAccount.DateOfBirth - ); - _ = command.Parameters.AddWithValue( - "@Timer", - userAccount.Timer ?? (object)DBNull.Value - ); - - connection.Open(); - _ = command.ExecuteNonQuery(); - } + } public UserAccount? GetById(Guid id) { - const string query = - "SELECT * FROM UserAccount WHERE UserAccountID = @UserAccountID;"; - - using (var connection = new SqlConnection(_connectionString)) - using (var command = new SqlCommand(query, connection)) - { - _ = command.Parameters.AddWithValue("@UserAccountID", id); - - connection.Open(); - using (var reader = command.ExecuteReader()) - { - if (reader.Read()) - { - return new UserAccount - { - UserAccountID = reader.GetGuid( - reader.GetOrdinal("UserAccountID") - ), - Username = reader.GetString( - reader.GetOrdinal("Username") - ), - FirstName = reader.GetString( - reader.GetOrdinal("FirstName") - ), - LastName = reader.GetString( - reader.GetOrdinal("LastName") - ), - Email = reader.GetString( - reader.GetOrdinal("Email") - ), - CreatedAt = reader.GetDateTime( - reader.GetOrdinal("CreatedAt") - ), - UpdatedAt = reader.IsDBNull( - reader.GetOrdinal("UpdatedAt") - ) - ? null - : reader.GetDateTime( - reader.GetOrdinal("UpdatedAt") - ), - DateOfBirth = reader.GetDateTime( - reader.GetOrdinal("DateOfBirth") - ), - Timer = reader.IsDBNull(reader.GetOrdinal("Timer")) - ? null - : (byte[])reader["Timer"], - }; - } - } - } - + return null; } public void Update(UserAccount userAccount) { - const string query = - @"UPDATE UserAccount - SET Username = @Username, FirstName = @FirstName, LastName = @LastName, Email = @Email, CreatedAt = @CreatedAt, UpdatedAt = @UpdatedAt, DateOfBirth = @DateOfBirth, Timer = @Timer - WHERE UserAccountID = @UserAccountID;"; - using (var connection = new SqlConnection(_connectionString)) - using (var command = new SqlCommand(query, connection)) - { - _ = command.Parameters.AddWithValue( - "@UserAccountID", - userAccount.UserAccountID - ); - _ = command.Parameters.AddWithValue( - "@Username", - userAccount.Username - ); - _ = command.Parameters.AddWithValue( - "@FirstName", - userAccount.FirstName - ); - _ = command.Parameters.AddWithValue( - "@LastName", - userAccount.LastName - ); - _ = command.Parameters.AddWithValue( - "@Email", - userAccount.Email - ); - _ = command.Parameters.AddWithValue( - "@CreatedAt", - userAccount.CreatedAt - ); - _ = command.Parameters.AddWithValue( - "@UpdatedAt", - userAccount.UpdatedAt ?? (object)DBNull.Value - ); - _ = command.Parameters.AddWithValue( - "@DateOfBirth", - userAccount.DateOfBirth - ); - _ = command.Parameters.AddWithValue( - "@Timer", - userAccount.Timer ?? (object)DBNull.Value - ); - - connection.Open(); - _ = command.ExecuteNonQuery(); - } } public void Delete(Guid id) { - const string query = - "DELETE FROM UserAccount WHERE UserAccountID = @UserAccountID;"; - - using (var connection = new SqlConnection(_connectionString)) - using (var command = new SqlCommand(query, connection)) - { - _ = command.Parameters.AddWithValue("@UserAccountID", id); - - connection.Open(); - _ = command.ExecuteNonQuery(); - } + } public IEnumerable GetAll() { - const string query = "SELECT * FROM UserAccount;"; - - var userAccounts = new List(); - - using (var connection = new SqlConnection(_connectionString)) - using (var command = new SqlCommand(query, connection)) - { - connection.Open(); - using (var reader = command.ExecuteReader()) - { - while (reader.Read()) - { - var userAccount = new UserAccount - { - UserAccountID = reader.GetGuid( - reader.GetOrdinal("UserAccountID") - ), - Username = reader.GetString( - reader.GetOrdinal("Username") - ), - FirstName = reader.GetString( - reader.GetOrdinal("FirstName") - ), - LastName = reader.GetString( - reader.GetOrdinal("LastName") - ), - Email = reader.GetString( - reader.GetOrdinal("Email") - ), - CreatedAt = reader.GetDateTime( - reader.GetOrdinal("CreatedAt") - ), - UpdatedAt = reader.IsDBNull( - reader.GetOrdinal("UpdatedAt") - ) - ? null - : reader.GetDateTime( - reader.GetOrdinal("UpdatedAt") - ), - DateOfBirth = reader.GetDateTime( - reader.GetOrdinal("DateOfBirth") - ), - Timer = reader.IsDBNull(reader.GetOrdinal("Timer")) - ? null - : (byte[])reader["Timer"], - }; - - userAccounts.Add(userAccount); - } - } - } - - return userAccounts; + return new List + { + }; } } } diff --git a/DataLayer/crud/UserAccount.sql b/DataLayer/crud/UserAccount.sql new file mode 100644 index 0000000..06b19e4 --- /dev/null +++ b/DataLayer/crud/UserAccount.sql @@ -0,0 +1,100 @@ +USE Biergarten; +GO + +CREATE OR ALTER PROCEDURE usp_CreateUserAccount +( + @Username VARCHAR(64), + @FirstName NVARCHAR(128), + @LastName NVARCHAR(128), + @DateOfBirth DATETIME, + @Email VARCHAR(128) +) +AS +BEGIN + SET NOCOUNT ON + SET XACT_ABORT ON + BEGIN TRANSACTION + + INSERT INTO UserAccount + ( + Username, + FirstName, + LastName, + DateOfBirth, + Email + ) + VALUES + ( + @Username, + @FirstName, + @LastName, + @DateOfBirth, + @Email + ); + + + + COMMIT TRANSACTION +END; +GO + +CREATE OR ALTER PROCEDURE usp_DeleteUserAccount +( + @UserAccountId INT +) +AS +BEGIN + SET NOCOUNT ON + SET XACT_ABORT ON + BEGIN TRANSACTION + + IF NOT EXISTS (SELECT 1 FROM UserAccount WHERE UserAccountId = @UserAccountId) + BEGIN + RAISERROR('UserAccount with the specified ID does not exist.', 16, + 1); + ROLLBACK TRANSACTION + RETURN + END + + DELETE FROM UserAccount + WHERE UserAccountId = @UserAccountId; + COMMIT TRANSACTION +END; +GO + + +CREATE OR ALTER PROCEDURE usp_UpdateUserAccount +( + @Username VARCHAR(64), + @FirstName NVARCHAR(128), + @LastName NVARCHAR(128), + @DateOfBirth DATETIME, + @Email VARCHAR(128), + @UserAccountId GUID +) +AS +BEGIN + SET NOCOUNT ON + SET XACT_ABORT ON + BEGIN TRANSACTION + + IF NOT EXISTS (SELECT 1 FROM UserAccount WHERE UserAccountId = @UserAccountId) + BEGIN + RAISERROR('UserAccount with the specified ID does not exist.', 16, + 1); + ROLLBACK TRANSACTION + RETURN + END + + UPDATE UserAccount + SET + Username = @Username, + FirstName = @FirstName, + LastName = @LastName, + DateOfBirth = @DateOfBirth, + Email = @Email + WHERE UserAccountId = @UserAccountId; + + COMMIT TRANSACTION +END; +GO diff --git a/DataLayer/schema.sql b/DataLayer/schema.sql index c204ba7..6f42575 100644 --- a/DataLayer/schema.sql +++ b/DataLayer/schema.sql @@ -22,7 +22,7 @@ USE Biergarten; ---------------------------------------------------------------------------- ---------------------------------------------------------------------------- -CREATE TABLE UserAccount +CREATE TABLE dbo.UserAccount ( UserAccountID UNIQUEIDENTIFIER CONSTRAINT DF_UserAccountID DEFAULT NEWID(), diff --git a/WebAPI/Program.cs b/WebAPI/Program.cs index 6a53a1e..5421649 100644 --- a/WebAPI/Program.cs +++ b/WebAPI/Program.cs @@ -1,3 +1,33 @@ +// Load a local .env file into environment variables when present (useful for local development) +try +{ + var envPath = Path.Combine(Directory.GetCurrentDirectory(), ".env"); + if (File.Exists(envPath)) + { + foreach (var line in File.ReadAllLines(envPath)) + { + var trimmed = line.Trim(); + if (string.IsNullOrEmpty(trimmed) || trimmed.StartsWith("#")) + continue; + var idx = trimmed.IndexOf('='); + if (idx <= 0) + continue; + var key = trimmed.Substring(0, idx).Trim(); + var val = trimmed.Substring(idx + 1).Trim(); + if (val.Length >= 2 && ((val.StartsWith("\"") && val.EndsWith("\"")) || (val.StartsWith("'") && val.EndsWith("'")))) + { + val = val.Substring(1, val.Length - 2); + } + if (Environment.GetEnvironmentVariable(key) == null) + Environment.SetEnvironmentVariable(key, val); + } + } +} +catch +{ + // If dotenv loading fails, continue without blocking startup. +} + var builder = WebApplication.CreateBuilder(args); // Add services to the container. diff --git a/docker-compose.yml b/docker-compose.yml index 98e83bf..9e9e004 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,15 +3,15 @@ services: image: mcr.microsoft.com/mssql/server:2022-latest platform: linux/amd64 container_name: sqlserver + env_file: + - .env environment: ACCEPT_EULA: "Y" - SA_PASSWORD: "YourStrong!Passw0rd" - ports: - - "1433:1433" + SA_PASSWORD: "${SA_PASSWORD}" volumes: - sqlserverdata:/var/opt/mssql healthcheck: - test: [ "CMD", "/opt/mssql-tools/bin/sqlcmd", "-S", "localhost", "-U", "sa", "-P", "YourStrong!Passw0rd", "-Q", "SELECT 1" ] + test: [ "CMD", "/opt/mssql-tools/bin/sqlcmd", "-S", "localhost", "-U", "sa", "-P", "${SA_PASSWORD}", "-Q", "SELECT 1" ] interval: 10s timeout: 5s retries: 12 @@ -21,8 +21,8 @@ services: redis: image: redis:7 container_name: redis - ports: - - "6379:6379" + env_file: + - .env networks: - devnet healthcheck: @@ -32,7 +32,7 @@ services: retries: 5 dotnet: - image: mcr.microsoft.com/dotnet/sdk:9.0 + image: mcr.microsoft.com/dotnet/sdk:10.0 container_name: dotnet-sdk tty: true stdin_open: true @@ -45,8 +45,8 @@ services: DOTNET_CLI_TELEMETRY_OPTOUT: "1" HOME: /home/dev USER: dev - DB_CONNECTION_STRING: "Server=sqlserver,1433;User Id=sa;Password=YourStrong!Passw0rd;Encrypt=True;TrustServerCertificate=True;Connection Timeout=30;Database=Biergarten;" - REDIS_URL: "redis:6379" + DB_CONNECTION_STRING: "Server=sqlserver,1433;User Id=sa;Password=${SA_PASSWORD};Encrypt=True;TrustServerCertificate=True;Connection Timeout=30;Database=${DB_NAME};" + REDIS_URL: "${REDIS_URL}" user: root networks: - devnet