mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-02-16 18:52:06 +00:00
Refactor UserAccount repository methods and add stored procedures for user account management
This commit is contained in:
@@ -18,239 +18,34 @@ namespace DataAccessLayer
|
|||||||
?? throw new InvalidOperationException(
|
?? throw new InvalidOperationException(
|
||||||
"The connection string is not set in the environment variables."
|
"The connection string is not set in the environment variables."
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Add(UserAccount userAccount)
|
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)
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update(UserAccount userAccount)
|
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)
|
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<UserAccount> GetAll()
|
public IEnumerable<UserAccount> GetAll()
|
||||||
{
|
{
|
||||||
const string query = "SELECT * FROM UserAccount;";
|
return new List<UserAccount>
|
||||||
|
{
|
||||||
var userAccounts = new List<UserAccount>();
|
};
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
100
DataLayer/crud/UserAccount.sql
Normal file
100
DataLayer/crud/UserAccount.sql
Normal file
@@ -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
|
||||||
@@ -22,7 +22,7 @@ USE Biergarten;
|
|||||||
----------------------------------------------------------------------------
|
----------------------------------------------------------------------------
|
||||||
----------------------------------------------------------------------------
|
----------------------------------------------------------------------------
|
||||||
|
|
||||||
CREATE TABLE UserAccount
|
CREATE TABLE dbo.UserAccount
|
||||||
(
|
(
|
||||||
UserAccountID UNIQUEIDENTIFIER
|
UserAccountID UNIQUEIDENTIFIER
|
||||||
CONSTRAINT DF_UserAccountID DEFAULT NEWID(),
|
CONSTRAINT DF_UserAccountID DEFAULT NEWID(),
|
||||||
|
|||||||
@@ -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);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
// Add services to the container.
|
// Add services to the container.
|
||||||
|
|||||||
@@ -3,15 +3,15 @@ services:
|
|||||||
image: mcr.microsoft.com/mssql/server:2022-latest
|
image: mcr.microsoft.com/mssql/server:2022-latest
|
||||||
platform: linux/amd64
|
platform: linux/amd64
|
||||||
container_name: sqlserver
|
container_name: sqlserver
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
environment:
|
environment:
|
||||||
ACCEPT_EULA: "Y"
|
ACCEPT_EULA: "Y"
|
||||||
SA_PASSWORD: "YourStrong!Passw0rd"
|
SA_PASSWORD: "${SA_PASSWORD}"
|
||||||
ports:
|
|
||||||
- "1433:1433"
|
|
||||||
volumes:
|
volumes:
|
||||||
- sqlserverdata:/var/opt/mssql
|
- sqlserverdata:/var/opt/mssql
|
||||||
healthcheck:
|
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
|
interval: 10s
|
||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 12
|
retries: 12
|
||||||
@@ -21,8 +21,8 @@ services:
|
|||||||
redis:
|
redis:
|
||||||
image: redis:7
|
image: redis:7
|
||||||
container_name: redis
|
container_name: redis
|
||||||
ports:
|
env_file:
|
||||||
- "6379:6379"
|
- .env
|
||||||
networks:
|
networks:
|
||||||
- devnet
|
- devnet
|
||||||
healthcheck:
|
healthcheck:
|
||||||
@@ -32,7 +32,7 @@ services:
|
|||||||
retries: 5
|
retries: 5
|
||||||
|
|
||||||
dotnet:
|
dotnet:
|
||||||
image: mcr.microsoft.com/dotnet/sdk:9.0
|
image: mcr.microsoft.com/dotnet/sdk:10.0
|
||||||
container_name: dotnet-sdk
|
container_name: dotnet-sdk
|
||||||
tty: true
|
tty: true
|
||||||
stdin_open: true
|
stdin_open: true
|
||||||
@@ -45,8 +45,8 @@ services:
|
|||||||
DOTNET_CLI_TELEMETRY_OPTOUT: "1"
|
DOTNET_CLI_TELEMETRY_OPTOUT: "1"
|
||||||
HOME: /home/dev
|
HOME: /home/dev
|
||||||
USER: dev
|
USER: dev
|
||||||
DB_CONNECTION_STRING: "Server=sqlserver,1433;User Id=sa;Password=YourStrong!Passw0rd;Encrypt=True;TrustServerCertificate=True;Connection Timeout=30;Database=Biergarten;"
|
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:6379"
|
REDIS_URL: "${REDIS_URL}"
|
||||||
user: root
|
user: root
|
||||||
networks:
|
networks:
|
||||||
- devnet
|
- devnet
|
||||||
|
|||||||
Reference in New Issue
Block a user