Merge pull request #3 from Crylia/database

Database
This commit is contained in:
KaiokenKiller
2024-07-06 11:45:56 +02:00
committed by GitHub
8 changed files with 778 additions and 0 deletions

25
DBHandler/DBHandler.cpp Normal file
View File

@@ -0,0 +1,25 @@
#include "DBHandler.hpp"
#include <iostream>
//host = localhost port = 5432 dbname = postgres user = postgres password = ****
DBHandler::DBHandler(std::string connStr) : connectionObject(connStr.c_str()) {
try {
if (connectionObject.is_open()) {
std::cout << "Databased connected" << std::endl;
}
else
std::cout << "Failed to connect to Databased" << std::endl;
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
};

14
DBHandler/DBHandler.hpp Normal file
View File

@@ -0,0 +1,14 @@
#ifndef DBHANDLER_HPP_
#define DBHANDLER_HPP_
#include <pqxx/pqxx>
#include <string>
class DBHandler {
protected:
pqxx::connection connectionObject;
public:
DBHandler(std::string connStr);
};
#endif

41
DBHandler/DBLogin.cpp Normal file
View File

@@ -0,0 +1,41 @@
#include "DBLogin.hpp"
#include <iostream>
DBLogin::DBLogin(std::string connStr) : DBHandler(connStr) {};
/*
return 1 if admin | 0 if not admin | -1 if failed
*/
int DBLogin::checkValidLogin(std::string id, std::string pw) {
try {
pqxx::work worker(connectionObject);
std::string query =
"SELECT admin FROM studenten_veranstalter WHERE id = $1 AND passwort = $2";
pqxx::result response = worker.exec_params(query, id, pw);
if (response.affected_rows() > 0) {
if (response[0][0].is_null())
return 0;
return response[0][0].as<bool>();
}
return -1;
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
}

18
DBHandler/DBLogin.hpp Normal file
View File

@@ -0,0 +1,18 @@
#ifndef _DBLOGIN_HPP_
#define _DBLOGIN_HPP_
#include "DBHandler.hpp"
class DBLogin : public DBHandler {
public:
DBLogin(std::string connStr);
/*
return 1 if admin | 0 if not admin | -1 if failed
*/
int checkValidLogin(std::string id, std::string pw);
};
#endif

477
DBHandler/DBPlan.cpp Normal file
View File

@@ -0,0 +1,477 @@
#include "DBPlan.hpp"
DBPlan::DBPlan(std::string connStr) : DBHandler(connStr) {
};
void DBPlan::vertretung(std::string tag, std::string stunde, std::string dauer) {
try {
std::string prevStunde = std::to_string(std::stoi(stunde) - 1);
std::string cap = std::to_string(18 - std::stoi(dauer));
std::string nextStunde;
std::string nextTag = tag;
std::string prevTag = tag;
if (dauer == "4") {
nextStunde = std::to_string(std::stoi(stunde) + 2);
std::cout << nextStunde << std::endl;
}
else {
nextStunde = std::to_string(std::stoi(stunde) + 1);
std::cout << nextStunde << std::endl;
}
if (prevStunde == "0") {
prevStunde = "5";
prevTag = std::to_string(std::stoi(tag) - 1);
if (prevTag == "0") {
prevTag = "5";
}
}
if (nextStunde == "6") {
nextStunde = "1";
nextTag = std::to_string(std::stoi(tag)+1);
if (nextTag == "6") {
nextTag = "1";
}
}
pqxx::work worker(connectionObject);
std::string query =
"UPDATE Veranstalter_Veranstaltung_Uhrzeit SET Veranstalter_ID = "
"(SELECT ID FROM Veranstalter WHERE ID != (SELECT Veranstalter_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $1 AND tag = $2) "
"AND ID != (SELECT Veranstalter_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $3 AND tag = $4) LIMIT 1) WHERE uhrzeit_id = $5 AND tag = $6; ";
pqxx::result response = worker.exec_params(query, prevStunde, prevTag, nextStunde, nextTag, stunde, tag);
worker.commit();
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
}
void DBPlan::sucheVertretung(std::string tag, std::string stunde) {
std::string dauer = getDauer(tag, stunde);
vertretung(tag, stunde, dauer);
incarbeitszeit(tag, stunde, dauer);
if (dauer == "4") {
upperHour(tag, stunde);
}
}
void DBPlan::meldeKrank(std::string id, std::string tag, std::string stunde) {
try {
pqxx::work worker(connectionObject);
std::string query =
"UPDATE Veranstalter SET krank = TRUE WHERE ID = $1";
pqxx::result response = worker.exec_params(query, id);
worker.commit();
sucheVertretung(tag, stunde);
meldeGesund(id);
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
}
void DBPlan::meldeGesund(std::string id) {
try {
pqxx::work worker(connectionObject);
std::string query =
"UPDATE Veranstalter SET krank = FALSE WHERE ID = $1";
pqxx::result response = worker.exec_params(query, id);
worker.commit();
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
}
void DBPlan::deleteVeranstalterForeign(std::string id) {
try {
pqxx::work worker(connectionObject);
std::string query =
"UPDATE Veranstalter_Veranstaltung_Uhrzeit SET Veranstalter_ID = NULL WHERE Veranstalter_ID = $1;";
pqxx::result response = worker.exec_params(query, id);
worker.commit();
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
}
void DBPlan::deleteVeranstalter(std::string id) {
deleteVeranstalterForeign(id);
try {
pqxx::work worker(connectionObject);
std::string query =
"DELETE FROM Veranstalter WHERE ID = $1";
pqxx::result response = worker.exec_params(query, id);
worker.commit();
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
}
void DBPlan::deleteVeranstaltungForeign(std::string id) {
try {
pqxx::work worker(connectionObject);
std::string query =
"UPDATE Veranstalter_Veranstaltung_Uhrzeit SET Veranstaltung_ID = NULL WHERE Veranstalter_ID = $1;";
pqxx::result response = worker.exec_params(query, id);
worker.commit();
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
}
void DBPlan::deleteVeranstaltung(std::string id) {
deleteVeranstaltungForeign(id);
try {
pqxx::work worker(connectionObject);
std::string query =
"DELETE FROM Veranstaltung WHERE ID = $1";
pqxx::result response = worker.exec_params(query, id);
worker.commit();
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
}
void DBPlan::hinzufuegenVeranstaltung(std::string name, std::string dauer, std::string ort, std::string raum) {
try {
pqxx::work worker(connectionObject);
std::string query =
"INSERT INTO Veranstaltung (name, dauer, ort, raum) VALUES ($1, $2, $3, $4);";
pqxx::result response = worker.exec_params(query, name, dauer, ort, raum);
worker.commit();
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
}
void DBPlan::hinzufuegenVeranstalter(std::string email, std::string name, std::string pw, std::string admin) {
try {
pqxx::work worker(connectionObject);
std::string query =
"INSERT INTO Veranstaltung (email, name, pw, admin) VALUES ($1, $2, $3, $4);";
pqxx::result response = worker.exec_params(query, email, name, pw, admin);
worker.commit();
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
}
void DBPlan::deleteStudent(std::string id) {
try {
pqxx::work worker(connectionObject);
std::string query =
"DELETE FROM studenten WHERE ID = $1;";
pqxx::result response = worker.exec_params(query, id);
worker.commit();
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
}
void DBPlan::hinzufuegenStudent(std::string email, std::string name, std::string pw) {
try {
pqxx::work worker(connectionObject);
std::string query =
"INSERT INTO studenten (email, name, pw) VALUES ($1, $2, $3);";
pqxx::result response = worker.exec_params(query, email, name, pw);
worker.commit();
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
}
std::string DBPlan::getDauer(std::string tag, std::string stunde) {
try {
pqxx::work worker(connectionObject);
std::string query =
"SELECT dauer FROM Veranstaltung WHERE ID = (SELECT Veranstaltung_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $1 AND tag = $2);";
pqxx::result response = worker.exec_params(query, stunde, tag);
worker.commit();
return response[0][0].c_str();
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
}
void DBPlan::addFirstOfDayTwo(std::string tag) {
try {
pqxx::work worker(connectionObject);
std::string query =
"UPDATE Veranstalter_Veranstaltung_Uhrzeit SET Veranstalter_ID = (SELECT ID FROM Veranstalter WHERE arbeitszeit <= 16 AND krank = FALSE LIMIT 1) "
"WHERE uhrzeit_id = 1 AND tag = $1;";
pqxx::result response = worker.exec_params(query, tag);
worker.commit();
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
}
void DBPlan::addTwoHour(std::string tag, std::string stunde) {
try {
std::string prevStunde = std::to_string(std::stoi(stunde) - 1);
std::cout << " prevStunde: " << prevStunde << " Tag: " << tag << " stunde " << stunde << std::endl;
pqxx::work worker(connectionObject);
std::string query =
"UPDATE Veranstalter_Veranstaltung_Uhrzeit SET Veranstalter_id = (SELECT ID FROM Veranstalter "
"WHERE arbeitszeit <= 16 AND krank = FALSE "
"AND(standort = (SELECT ort FROM Veranstaltung WHERE ID = (SELECT veranstaltung_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $1 AND tag = $2)) "
"AND ID != (SELECT veranstalter_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $1 AND tag = $2)) "
"ORDER BY random() LIMIT 1) "
"WHERE uhrzeit_id = $3 AND tag = $4;";
pqxx::result response = worker.exec_params(query, prevStunde, tag, stunde, tag);
worker.commit();
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
}
void DBPlan::addFirstOfDayFour(std::string tag) {
try {
pqxx::work worker(connectionObject);
std::string query =
"UPDATE Veranstalter_Veranstaltung_Uhrzeit SET Veranstalter_ID = (SELECT ID FROM Veranstalter WHERE arbeitszeit <= 14 AND krank = FALSE LIMIT 1) "
"WHERE uhrzeit_id = 1 AND tag = $1;";
pqxx::result response = worker.exec_params(query, tag);
worker.commit();
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
}
void DBPlan::addFourHour(std::string tag, std::string stunde) {
try {
std::string prevStunde = std::to_string(std::stoi(stunde) - 1);
pqxx::work worker(connectionObject);
std::string query =
"UPDATE Veranstalter_Veranstaltung_Uhrzeit SET Veranstalter_id = (SELECT ID FROM Veranstalter "
"WHERE arbeitszeit <= 14 AND krank = FALSE "
"AND(standort = (SELECT ort FROM Veranstaltung WHERE ID = (SELECT veranstaltung_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $1 AND tag = $2)) "
"AND ID != (SELECT veranstalter_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $1 AND tag = $2)) "
"ORDER BY random() LIMIT 1) "
"WHERE uhrzeit_id = $3 AND tag = $4;";
pqxx::result response = worker.exec_params(query, prevStunde, tag, stunde, tag);
worker.commit();
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
}
void DBPlan::upperHour(std::string tag, std::string stunde) {
try {
std::string nextStunde = std::to_string(std::stoi(stunde) + 1);
pqxx::work worker(connectionObject);
std::string query =
"UPDATE Veranstalter_Veranstaltung_Uhrzeit SET Veranstalter_ID = (SELECT Veranstalter_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $1 AND tag = $2)"
"WHERE uhrzeit_id = $3 AND tag = $2;";
pqxx::result response = worker.exec_params(query, stunde, tag, nextStunde);
worker.commit();
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
}
void DBPlan::updateStandort(std::string tag, std::string stunde) {
try {
pqxx::work worker(connectionObject);
std::string query =
"UPDATE Veranstalter SET standort = (SELECT ort FROM Veranstaltung WHERE ID = (SELECT Veranstaltung_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $1 AND tag = $2)) WHERE ID = (SELECT Veranstalter_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $1 AND tag = $2);";
pqxx::result response = worker.exec_params(query, stunde, tag);
worker.commit();
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
}
void DBPlan::incarbeitszeit(std::string tag, std::string stunde, std::string amount) {
try {
pqxx::work worker(connectionObject);
std::string query =
"UPDATE Veranstalter SET arbeitszeit = arbeitszeit + $1 WHERE ID = (SELECT Veranstalter_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $2 AND tag = $3);";
pqxx::result response = worker.exec_params(query,amount, stunde, tag);
worker.commit();
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
}
void DBPlan::createPlan() {
try {
for (int tag = 1; tag < 6; tag++) {
std::string tagStr = std::to_string(tag);
for (int stunde = 1; stunde < 6; stunde++) {
std::string stundeStr = std::to_string(stunde);
//get dauer of next class
if (std::stoi(getDauer(tagStr, stundeStr)) == 2) {
if (stunde == 1) {
addFirstOfDayTwo(tagStr);
}
else {
addTwoHour(tagStr, stundeStr);
}
updateStandort(tagStr, stundeStr);
incarbeitszeit(tagStr, stundeStr, "2");
}
else {
if (stunde == 1) {
addFirstOfDayFour(tagStr);
}
else {
addFourHour(tagStr, stundeStr);
}
upperHour(tagStr, stundeStr);
incarbeitszeit(tagStr, stundeStr, "4");
updateStandort(tagStr, stundeStr);
stunde++;
}
}
}
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
}
std::vector<std::string> DBPlan::getPlan() {
try {
std::vector<std::string> plan;
pqxx::work worker(connectionObject);
std::string query =
"SELECT tag, u.anfangszeit, u.endzeit, o.ort, o.name, v.name, v.ID FROM Veranstalter_Veranstaltung_Uhrzeit LEFT JOIN Veranstalter v ON Veranstalter_Veranstaltung_Uhrzeit.veranstalter_ID = v.ID "
"LEFT JOIN Uhrzeit u ON Veranstalter_Veranstaltung_Uhrzeit.uhrzeit_ID = u.ID "
"LEFT JOIN Veranstaltung o ON Veranstalter_Veranstaltung_Uhrzeit.veranstaltung_ID = o.ID "
"ORDER BY tag, uhrzeit_ID;";
pqxx::result response = worker.exec(query);
worker.commit();
for (const auto& row : response) {
std::string rowstring;
for (const auto& col : row) {
rowstring.append(col.c_str());
rowstring.append(" , ");
}
plan.push_back(rowstring);
}
return plan;
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
}

50
DBHandler/DBPlan.hpp Normal file
View File

@@ -0,0 +1,50 @@
#ifndef _DBPLAN_HPP_
#define _DBPLAN_HPP_
#include "DBHandler.hpp"
#include <iostream>
#include <vector>
class DBPlan : public DBHandler {
private:
//Functions needed for creation and updating of the plan
std::string getDauer(std::string tag, std::string stunde);
void addFirstOfDayTwo(std::string tag);
void addTwoHour(std::string tag, std::string stunde);
void addFirstOfDayFour(std::string tag);
void upperHour(std::string tag, std::string stunde);
void addFourHour(std::string tag, std::string stunde);
void sucheVertretung(std::string tag, std::string stunde);
void vertretung(std::string tag, std::string stunde, std::string dauer);
void deleteVeranstalterForeign(std::string id);
void deleteVeranstaltungForeign(std::string id);
void updateStandort(std::string tag, std::string stunde);
void incarbeitszeit(std::string tag, std::string stunde, std::string amount);
public:
DBPlan(std::string connStr);
void meldeKrank(std::string id, std::string tag, std::string stunde);
void meldeGesund(std::string id);
void deleteVeranstaltung(std::string id);
void hinzufuegenVeranstaltung(std::string name, std::string dauer, std::string ort, std::string raum);
void deleteVeranstalter(std::string id);
void hinzufuegenVeranstalter(std::string email, std::string name, std::string pw, std::string admin);
void deleteStudent(std::string id);
void hinzufuegenStudent(std::string email, std::string name, std::string pw);
void createPlan();
//Each string in form of (tag , anfangszeit , endzeit , Ort , Veranstaltung , Mitarbeiter , mitarbeiterID , )
std::vector<std::string> getPlan();
};
#endif

2
README Normal file
View File

@@ -0,0 +1,2 @@
Code written with libpqxx-version 7.4.1
install-guide: http://en.wiki.imlint.org/Pqxx_tutorial

151
script.sql Normal file
View File

@@ -0,0 +1,151 @@
DROP VIEW studenten_veranstalter;
DROP TABLE Veranstalter_Veranstaltung_Uhrzeit;
DROP TABLE Studenten;
DROP TABLE Veranstalter;
DROP TABLE Uhrzeit;
DROP TABLE veranstaltung;
DROP SEQUENCE global_id_seq;
CREATE SEQUENCE global_id_seq;
CREATE TABLE Studenten (
matrikelnummer INTEGER PRIMARY KEY DEFAULT nextval('global_id_seq'),
name VARCHAR(30) NOT NULL,
email VARCHAR(30) NOT NULL,
passwort VARCHAR(30) NOT NULL
);
CREATE OR REPLACE FUNCTION random_between_two()
RETURNS VARCHAR AS $$
BEGIN
IF random() < 0.5 THEN
RETURN 'A';
ELSE
RETURN 'B';
END IF;
END;
$$ LANGUAGE plpgsql;
CREATE TABLE Veranstalter (
ID INTEGER PRIMARY KEY DEFAULT nextval('global_id_seq'),
name VARCHAR(30),
email VARCHAR(30),
passwort VARCHAR(30),
arbeitszeit INTEGER DEFAULT 0,
standort VARCHAR(30) DEFAULT random_between_two(),
krank BOOLEAN DEFAULT FALSE,
admin BOOLEAN NOT NULL DEFAULT FALSE
);
CREATE VIEW studenten_veranstalter AS
SELECT matrikelnummer AS id, passwort, NULL AS admin FROM Studenten
UNION ALL
SELECT ID, passwort, admin FROM Veranstalter;
CREATE TABLE Veranstaltung (
ID SERIAL PRIMARY KEY,
ort VARCHAR(30) NOT NULL,
raum INTEGER NOT NULL,
name VARCHAR(90) NOT NULL,
dauer INTEGER NOT NULL
);
CREATE TABLE Uhrzeit (
ID SERIAL PRIMARY KEY,
anfangszeit TIME NOT NULL,
endzeit TIME NOT NULL );
INSERT INTO Uhrzeit (anfangszeit, endzeit) VALUES
('08:00:00', '10:00:00'),
('10:00:00', '12:00:00'),
('12:00:00', '14:00:00'),
('14:00:00', '16:00:00'),
('16:00:00', '18:00:00');
CREATE TABLE Veranstalter_Veranstaltung_Uhrzeit (
uhrzeit_ID INTEGER REFERENCES Uhrzeit(ID),
tag INTEGER NOT NULL,
veranstalter_ID INTEGER REFERENCES Veranstalter(ID),
veranstaltung_ID INTEGER REFERENCES Veranstaltung(ID),
PRIMARY KEY(uhrzeit_ID, tag)
);
INSERT INTO Veranstalter (name, email, passwort, admin) VALUES
('tech_guru', 'admin@example.com', 'password123', TRUE),
('code_master', 'user1@example.com', 'password1', FALSE),
('binary_hero', 'user2@example.com', 'password2', FALSE),
('debug_ninja', 'user3@example.com', 'password3', FALSE),
('data_wizard', 'user4@example.com', 'password4', FALSE),
('script_samurai', 'user5@example.com', 'password5', FALSE),
('dev_genius', 'user6@example.com', 'password6', FALSE),
('cyber_maven', 'user7@example.com', 'password7', FALSE),
('net_knight', 'user8@example.com', 'password8', FALSE),
('bit_boss', 'user9@example.com', 'password9', FALSE),
('sys_sensei', 'user10@example.com', 'password10', FALSE),
('crypto_champ', 'user11@example.com', 'password11', FALSE);
INSERT INTO Veranstaltung (ort, raum, name, dauer) VALUES
('A', '101', 'Grundlagen der Programmierung', 2),
('B', '202', 'Algorithmen und Datenstrukturen', 4),
('A', '103', 'Netzwerkgrundlagen', 2),
('B', '204', 'Betriebssystemkonzepte', 4),
('A', '105', 'Softwareentwicklung', 2),
('B', '206', 'Intelligente Systeme', 4),
('A', '107', 'Datenbanksysteme', 2),
('B', '208', 'Webtechnologien', 2),
('A', '109', 'Computergrafikgrundlagen', 2),
('B', '210', 'Maschinelles Lernen', 2);
INSERT INTO Veranstalter_Veranstaltung_Uhrzeit (uhrzeit_ID, tag, veranstaltung_ID) VALUES
(1, 1, 1),
(2, 1, 7),
(3, 1, 8),
(4, 1, 3),
(5, 1, 10),
(1, 2, 4),
(2, 2, 4),
(3, 2, 5),
(4, 2, 6),
(5, 2, 6),
(1, 3, 7),
(2, 3, 8),
(3, 3, 9),
(4, 3, 10),
(5, 3, 1),
(1, 4, 2),
(2, 4, 2),
(3, 4, 3),
(4, 4, 4),
(5, 4, 4),
(1, 5, 5),
(2, 5, 6),
(3, 5, 6),
(4, 5, 7),
(5, 5, 8);