325 lines
10 KiB
C#
325 lines
10 KiB
C#
using Ophelias.Models;
|
|
using System.Data.SQLite;
|
|
|
|
namespace Ophelias.Managers
|
|
{
|
|
internal class Database : IDisposable
|
|
{
|
|
/*
|
|
* This class provides some basic functions that
|
|
* mirror SQLite. The reason for this class is to include
|
|
* some functions on it that typically would be separate.
|
|
* In another world, these functions could be of another
|
|
* static class as they don't really serve a purpose other
|
|
* than a one-time use if the database needs initialization.
|
|
*/
|
|
internal SQLiteConnection con = new("DataSource=database.sqlite3;Version=3;");
|
|
|
|
internal Database()
|
|
{
|
|
Connect();
|
|
}
|
|
internal void Connect()
|
|
{
|
|
con.Open();
|
|
}
|
|
internal void Close()
|
|
{
|
|
con.Close();
|
|
con.Dispose();
|
|
}
|
|
internal void InitializeTables()
|
|
{
|
|
/*
|
|
* This string is used to create the tables used by the models
|
|
* and the database functions. For more details, see the formatting
|
|
* string below as it has been organized in such a way there it is readable.
|
|
*/
|
|
string tableCommands =
|
|
@"CREATE TABLE IF NOT EXISTS [transactions] (
|
|
[ID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
[Rate] INTEGER NOT NULL,
|
|
[Owed] INTEGER NOT NULL,
|
|
[Penalty] INTEGER NOT NULL,
|
|
[Multiplier] INTEGER NOT NULL,
|
|
[RefundAmount] INTEGER NOT NULL,
|
|
[AmountPaid] INTEGER NOT NULL,
|
|
[PayBy] TEXT NOT NULL,
|
|
[LastPaid] TEXT NULL,
|
|
[PaidOn] TEXT NULL);
|
|
|
|
CREATE TABLE IF NOT EXISTS [reservations] (
|
|
[ID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
[RoomNum] INTEGER NULL,
|
|
[GuestID] INTEGER NOT NULL,
|
|
[TransactionID] INTEGER NOT NULL UNIQUE,
|
|
[IsNoShow] BOOLEAN NOT NULL CHECK ([IsNoShow] IN (0,1)),
|
|
[Type] INTEGER NOT NULL CHECK ([Type] IN (0,1,2,3)),
|
|
[Status] INTEGER NOT NULL CHECK ([Status] IN (0,1,2,3)),
|
|
[CreationDate] TEXT NOT NULL,
|
|
[StartDate] TEXT NOT NULL,
|
|
[EndDate] TEXT NOT NULL,
|
|
[CheckIn] TEXT NULL,
|
|
[CheckOut] TEXT NULL,
|
|
[DateChanged] TEXT NULL,
|
|
FOREIGN KEY ([RoomNum]) REFERENCES rooms(ID),
|
|
FOREIGN KEY ([GuestID]) REFERENCES guests(ID),
|
|
FOREIGN KEY ([TransactionID]) REFERENCES transactions(ID));
|
|
|
|
CREATE TABLE IF NOT EXISTS [guests] (
|
|
[ID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
[Fname] TEXT NOT NULL,
|
|
[Lname] TEXT NOT NULL,
|
|
[Email] TEXT NOT NULL UNIQUE,
|
|
[CreditCard] TEXT NULL UNIQUE,
|
|
[Expiration] TEXT NULL,
|
|
[CCV] TEXT NULL);
|
|
|
|
CREATE TABLE IF NOT EXISTS [rooms] (
|
|
[ID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
[Occupied] BOOLEAN NOT NULL CHECK ([Occupied] IN (0,1)));
|
|
|
|
CREATE TABLE IF NOT EXISTS [rates] (
|
|
[ID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
[Rate] INTEGER NOT NULL,
|
|
[DateSet] TEXT NOT NULL UNIQUE,
|
|
[DefaultRate] INTEGER NULL UNIQUE CHECK ([DefaultRate] IN (1)));";
|
|
|
|
using SQLiteCommand cmd = con.CreateCommand();
|
|
cmd.CommandText = tableCommands;
|
|
cmd.ExecuteNonQuery();
|
|
}
|
|
|
|
internal void InitializeRoomsTable()
|
|
{
|
|
/*
|
|
* This is a one off initialization function to intialize
|
|
* a list of 45 rooms. The design specification called
|
|
* for a static 45 rooms that were not configurable hence
|
|
* it being hardcoded here for now. Ideally this is moved
|
|
* out to config file.
|
|
*/
|
|
using SQLiteCommand cmd = con.CreateCommand();
|
|
for (int i = 0; i < 45; i++)
|
|
{
|
|
cmd.CommandText = $"INSERT INTO ROOMS (Occupied) VALUES (0);";
|
|
cmd.ExecuteNonQuery();
|
|
}
|
|
}
|
|
public void Dispose() // Needed to support "using"
|
|
{
|
|
Close();
|
|
}
|
|
}
|
|
|
|
internal static class QueryBuilder
|
|
{
|
|
/*
|
|
* This class is for building update query strings. To prevent SQL injection
|
|
* on dynamically built strings, the inputs are now used as null check values,
|
|
* rather than as null check values that get set if they exist. Parameters are
|
|
* now used in their place which prevent SQL injection.
|
|
*/
|
|
internal static string? UpdateTransaction(int Id,
|
|
double? Rate = null, double? Owed = null, double? Penalty = null,
|
|
double? Multiplier = null, double? Refund = null,
|
|
DateTime? PayBy = null, DateTime? LastPaid = null, DateTime? PaidOn = null, double? AmountPaid = null)
|
|
{
|
|
/*
|
|
* Builds an update query string for the transaction model
|
|
*/
|
|
List<string> queryComponents = new();
|
|
string query = "UPDATE transactions SET";
|
|
|
|
if (Rate.HasValue)
|
|
{
|
|
queryComponents.Add($"Rate = @Rate");
|
|
}
|
|
|
|
if (Owed.HasValue)
|
|
{
|
|
queryComponents.Add($"Owed = @Owed");
|
|
}
|
|
|
|
if (Penalty.HasValue)
|
|
{
|
|
queryComponents.Add($"Penalty = @Penalty");
|
|
}
|
|
|
|
if (Multiplier.HasValue)
|
|
{
|
|
queryComponents.Add($"Multiplier = @Multiplier");
|
|
}
|
|
|
|
if (Refund.HasValue)
|
|
{
|
|
queryComponents.Add($"RefundAmount = @RefundAmount");
|
|
}
|
|
|
|
if (AmountPaid.HasValue)
|
|
{
|
|
queryComponents.Add($"AmountPaid = @AmountPaid");
|
|
}
|
|
|
|
if (PayBy.HasValue)
|
|
{
|
|
queryComponents.Add($"PayBy = @PayBy");
|
|
}
|
|
|
|
if (LastPaid.HasValue)
|
|
{
|
|
queryComponents.Add($"LastPaid = @LastPaid");
|
|
}
|
|
|
|
if (PaidOn.HasValue)
|
|
{
|
|
queryComponents.Add($"PaidOn = @PaidOn");
|
|
}
|
|
|
|
if (queryComponents.Count >= 0)
|
|
{
|
|
query += " " + string.Join(", ", queryComponents) + " " + $"WHERE ID = @ID;";
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return query;
|
|
}
|
|
|
|
internal static string? UpdateReservation(int Id,
|
|
int? RoomID = null, int? GuestID = null, int? TransactionID = null, bool? IsNoShow = null, ReservationType? Type = null,
|
|
ReservationStatus? Status = null, DateTime? CreationDate = null, DateTime? StartDate = null, DateTime? EndDate = null,
|
|
DateTime? CheckIn = null, DateTime? CheckOut = null, DateTime? DateChanged = null)
|
|
{
|
|
/*
|
|
* Builds an update query string for the reservation model
|
|
*/
|
|
List<string> QueryParts = new();
|
|
string query = "UPDATE reservations SET";
|
|
|
|
if (RoomID.HasValue)
|
|
{
|
|
QueryParts.Add($"RoomID = @RID");
|
|
}
|
|
|
|
if (GuestID.HasValue)
|
|
{
|
|
QueryParts.Add($"GuestID = @GID");
|
|
}
|
|
|
|
if (TransactionID.HasValue)
|
|
{
|
|
QueryParts.Add($"TransactionID = @TID");
|
|
}
|
|
|
|
if (IsNoShow.HasValue)
|
|
{
|
|
QueryParts.Add($"IsNoShow = @IsNoShow");
|
|
}
|
|
|
|
if (Type.HasValue)
|
|
{
|
|
QueryParts.Add($"Type = @Type");
|
|
}
|
|
|
|
if (Status.HasValue)
|
|
{
|
|
QueryParts.Add($"Status = @Status");
|
|
}
|
|
|
|
if (CreationDate.HasValue)
|
|
{
|
|
QueryParts.Add($"CreationDate = @CreationDate");
|
|
}
|
|
|
|
if (StartDate.HasValue)
|
|
{
|
|
QueryParts.Add($"StartDate = @StartDate");
|
|
}
|
|
|
|
if (EndDate.HasValue)
|
|
{
|
|
QueryParts.Add($"EndDate = @EndDate");
|
|
}
|
|
|
|
if (CheckIn.HasValue)
|
|
{
|
|
QueryParts.Add($"CheckIn = @CheckIn");
|
|
}
|
|
|
|
if (CheckOut.HasValue)
|
|
{
|
|
QueryParts.Add($"CheckOut = @CheckOut");
|
|
}
|
|
|
|
if (DateChanged.HasValue)
|
|
{
|
|
QueryParts.Add($"DateChanged = @DateChanged");
|
|
}
|
|
|
|
if (QueryParts.Count >= 0)
|
|
{
|
|
query += " " + string.Join(", ", QueryParts) + " " + $"WHERE ID = @ID;";
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return query;
|
|
}
|
|
|
|
internal static string? UpdateGuest(int Id, string? FirstName = null, string? LastName = null, string? Email = null, string? CreditCard = null, string? Expiration = null, string? CCV = null)
|
|
{
|
|
/*
|
|
* Builds an update query string for the guest model
|
|
*/
|
|
List<string> QueryParts = new();
|
|
string query = "UPDATE guests SET";
|
|
|
|
if (!string.IsNullOrEmpty(FirstName))
|
|
{
|
|
QueryParts.Add($"Fname = @Fname");
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(LastName))
|
|
{
|
|
QueryParts.Add($"Lname = @Lname");
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(LastName))
|
|
{
|
|
QueryParts.Add($"Email = @Email");
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(CreditCard))
|
|
{
|
|
QueryParts.Add($"CreditCard = @CreditCard");
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(Expiration))
|
|
{
|
|
QueryParts.Add($"Expiration = @Expiry");
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(CCV))
|
|
{
|
|
QueryParts.Add($"CCV = @CCV");
|
|
}
|
|
|
|
if (QueryParts.Count >= 0)
|
|
{
|
|
query += " " + string.Join(", ", QueryParts) + " " + $"WHERE ID = @ID;";
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return query;
|
|
}
|
|
}
|
|
}
|