597 lines
22 KiB
Java

package com.bib.essensbestellungsverwaltung;
/*
@author Malte Schulze Hobeling
*/
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class Database {
private static final String dbLocation = "jdbc:sqlite:"+Path.of("").toAbsolutePath()+"/database.db";
/**
* creates new database.db if it doesn't exist
* @return true if a new database has been created
*/
protected static boolean init(){
File db = new File(Path.of("").toAbsolutePath()+"/database.db");
try {
return db.createNewFile();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* connects to the database
* @return Connection to the database
*/
protected static Connection connect(){
Connection conn = null;
try{
conn = DriverManager.getConnection(dbLocation);
}catch (SQLException e){
e.printStackTrace();
}
return conn;
}
/**
* creates the initial structure of the db
*/
protected static void createDb(){
String[] sql = new String[14];
sql[0] = """
CREATE TABLE IF NOT EXISTS address (
id integer PRIMARY KEY,
street text,
number text,
plz text,
city text
);""";
sql[1] = """
CREATE TABLE IF NOT EXISTS food_type (
id integer PRIMARY KEY,
name text UNIQUE
);""";
sql[2] = """
CREATE TABLE IF NOT EXISTS allergy (
id integer PRIMARY KEY,
name text UNIQUE
);""";
sql[3] = """
CREATE TABLE IF NOT EXISTS severity (
id integer PRIMARY KEY,
name text UNIQUE
);""";
sql[4] = """
CREATE TABLE IF NOT EXISTS user (
id integer PRIMARY KEY,
name text,
firstname text,
addressid integer,
password text,
email text UNIQUE,
FOREIGN KEY(addressid) REFERENCES address(id)
);""";
sql[5] = """
CREATE TABLE IF NOT EXISTS child (
id integer PRIMARY KEY,
name text,
firstname text,
addressid integer,
FOREIGN KEY(addressid) REFERENCES address(id)
);""";
sql[6] = """
CREATE TABLE IF NOT EXISTS worker (
userid integer PRIMARY KEY,
FOREIGN KEY(userid) REFERENCES user(id)
);""";
sql[7] = """
CREATE TABLE IF NOT EXISTS parent (
userid integer PRIMARY KEY,
FOREIGN KEY(userid) REFERENCES user(id)
);""";
sql[8] = """
CREATE TABLE IF NOT EXISTS parent_child (
id integer PRIMARY KEY,
parentuserid integer,
childid integer,
FOREIGN KEY(parentuserid) REFERENCES parent(userid),
FOREIGN KEY(childid) REFERENCES child(id)
);""";
sql[9] = """
CREATE TABLE IF NOT EXISTS child_allergy (
id integer PRIMARY KEY,
childid integer,
allergyid integer,
severityid integer,
FOREIGN KEY(childid) REFERENCES child(id),
FOREIGN KEY(allergyid) REFERENCES allergy(id),
FOREIGN KEY(severityid) REFERENCES severity(id)
);""";
sql[10] = """
CREATE TABLE IF NOT EXISTS food (
id integer PRIMARY KEY,
name text UNIQUE,
description text,
isdessert integer,
food_typeid integer,
FOREIGN KEY(food_typeid) REFERENCES food_type(id)
);""";
sql[11] = """
CREATE TABLE IF NOT EXISTS food_plan (
id integer PRIMARY KEY,
date text UNIQUE,
food1 integer,
food2 integer,
dessert1 integer,
dessert2 integer,
issent integer DEFAULT '0',
FOREIGN KEY(food1) REFERENCES food(id),
FOREIGN KEY(food2) REFERENCES food(id),
FOREIGN KEY(dessert1) REFERENCES food(id),
FOREIGN KEY(dessert2) REFERENCES food(id)
);""";
sql[12] = """
CREATE TABLE IF NOT EXISTS food_restriction (
id integer PRIMARY KEY,
foodid integer,
allergyid integer,
FOREIGN KEY(foodid) REFERENCES food(id),
FOREIGN KEY(allergyid) REFERENCES allergy(id)
);""";
sql[13] = """
CREATE TABLE IF NOT EXISTS food_selection (
id integer PRIMARY KEY,
childid integer,
food_planid integer,
foodid integer,
FOREIGN KEY(childid) REFERENCES child(id),
FOREIGN KEY(food_planid) REFERENCES food_plan(id),
FOREIGN KEY(foodid) REFERENCES food(id)
);""";
try(Connection conn = connect(); Statement stmt = conn.createStatement()){
for(int i = 0; i < sql.length; i++){
stmt.execute(sql[i]);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* inserts fixed values into the database
*/
protected static void fillDb(){
List<String> sqls = new ArrayList<>();
sqls.add("""
INSERT OR IGNORE INTO food_type (id,name)
VALUES ('1','Vegan');""");
sqls.add("""
INSERT OR IGNORE INTO food_type (id,name)
VALUES ('2','Vegetarisch');""");
sqls.add("""
INSERT OR IGNORE INTO food_type (id,name)
VALUES ('3','Fleischhaltig');""");
sqls.add("""
INSERT OR IGNORE INTO allergy (id,name)
VALUES('1','Eier');""");
sqls.add("""
INSERT OR IGNORE INTO allergy (id,name)
VALUES('2','Soja');""");
sqls.add("""
INSERT OR IGNORE INTO allergy (id,name)
VALUES('3','Milch');""");
sqls.add("""
INSERT OR IGNORE INTO allergy (id,name)
VALUES('4','Erdnüsse');""");
sqls.add("""
INSERT OR IGNORE INTO allergy (id,name)
VALUES('5','Weichtiere');""");
sqls.add("""
INSERT OR IGNORE INTO allergy (id,name)
VALUES('6','Krebstiere');""");
sqls.add("""
INSERT OR IGNORE INTO allergy (id,name)
VALUES('7','Getreide');""");
sqls.add("""
INSERT OR IGNORE INTO allergy (id,name)
VALUES('8','Senf');""");
sqls.add("""
INSERT OR IGNORE INTO allergy (id,name)
VALUES('9','Sesam');""");
sqls.add("""
INSERT OR IGNORE INTO allergy (id,name)
VALUES('10','Schwefeldioxid und Sulfit');""");
sqls.add("""
INSERT OR IGNORE INTO allergy (id,name)
VALUES('11','Nüsse');""");
sqls.add("""
INSERT OR IGNORE INTO allergy (id,name)
VALUES('12','Sellerie');""");
sqls.add("""
INSERT OR IGNORE INTO allergy (id,name)
VALUES('13','Fische');""");
sqls.add("""
INSERT OR IGNORE INTO allergy (id,name)
VALUES('14','Lupinen');""");
sqls.add("""
INSERT OR IGNORE INTO allergy (id,name)
VALUES('15','Nitrit-Pökelsalz');""");
sqls.add("""
INSERT OR IGNORE INTO allergy (id,name)
VALUES('16','Phosphat');""");
sqls.add("""
INSERT OR IGNORE INTO allergy (id,name)
VALUES('17','Nitrat');""");
sqls.add("""
INSERT OR IGNORE INTO allergy (id,name)
VALUES('18','Antioxidationsmittel');""");
sqls.add("""
INSERT OR IGNORE INTO allergy (id,name)
VALUES('19','Farbstoff');""");
sqls.add("""
INSERT OR IGNORE INTO allergy (id,name)
VALUES('20','Geschmacksverstärker');""");
sqls.add("""
INSERT OR IGNORE INTO allergy (id,name)
VALUES('21','Süßungsmittel');""");
sqls.add("""
INSERT OR IGNORE INTO allergy (id,name)
VALUES('22','Konservierungsstoff');""");
sqls.add("""
INSERT OR IGNORE INTO severity (id,name)
VALUES('1','Harmlos');""");
sqls.add("""
INSERT OR IGNORE INTO severity (id,name)
VALUES('2','Warnung');""");
sqls.add("""
INSERT OR IGNORE INTO severity (id,name)
VALUES('3','Kritisch');""");
try(Connection conn = connect(); Statement stmt = conn.createStatement()){
for (String sql : sqls) {
stmt.execute(sql);
}
}catch (SQLException e){
e.printStackTrace();
}
}
/**
* inserts data into table and returns its id
* does not insert if the exact set already exists
* @param table name of the database table
* @param header String[] order should match with values
* @param values String[] order should match with header
* @return id of dataset or -1
*/
protected static long insert(String table, String[] header, String[] values){
long id = -1;
try (Connection conn = connect()){
String query = queryBuilder("exists",table,header,values);
PreparedStatement psQuery = conn.prepareStatement(query);
ResultSet rsQuery = psQuery.executeQuery();
if(rsQuery.next()){
boolean found = rsQuery.getBoolean(1);
if(!found){
String sql = queryBuilder("insert",table,header,values);
String[] rowId = {"id"};
PreparedStatement ps = conn.prepareStatement(sql,rowId);
ps.execute();
ResultSet rs = ps.getGeneratedKeys();
if(rs.next()){
id = rs.getLong(1);
}
}else{
query = queryBuilder("selectMatch",table,header,values);
psQuery = conn.prepareStatement(query);
rsQuery = psQuery.executeQuery();
if(rsQuery.next()) {
id = rsQuery.getLong(1);
}
}
}
} catch (SQLException e) {
return id;
}
return id;
}
/**
* returns a single id that matches the given data
* @param table the table that contains the searched entry
* @param header the header of the table, order should match with values
* @param values the data you want the id of, order should match witch values
* @return one id matching the given data or -1 if no match has been found
*/
protected static long getSingleId(String table, String[] header, String[] values){
long id = -1;
try(Connection conn = connect()){
String sql = queryBuilder("selectMatch",table,header,values);
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
if(rs.next()){
id = rs.getLong(1);
if(rs.next()){
id = -1;
}
}
}catch (SQLException e){
e.printStackTrace();
return id;
}
return id;
}
/**
* @deprecated
*/
protected static void printSampleQuery(){
String sql = """
SELECT * FROM food_type WHERE id > ?;""";
String sql1 = """
SELECT * FROM allergy WHERE id > ?;""";
try(Connection conn = connect()){
PreparedStatement ps = conn.prepareStatement(sql);
PreparedStatement ps1 = conn.prepareStatement(sql1);
ps.setInt(1,0);
ResultSet rs = ps.executeQuery();
System.out.println("food_type");
while (rs.next()){
System.out.println("ID: " + rs.getInt("id") + ", Name: " + rs.getString("name"));
}
System.out.println("allergy");
ps1.setInt(1,0);
rs = ps1.executeQuery();
while (rs.next()){
System.out.println("ID: " + rs.getInt("id") + ", Name: " + rs.getString("name"));
}
}catch (SQLException e){
e.printStackTrace();
}
}
/**
* deletes an entry from table with matching id
* @param table the table that contains the entry you want to delete
* @param id the id of the entry you want to delete
*/
protected static void delete(String table, long id){
String sql = "DELETE FROM " + table + " WHERE id = ?;";
try(Connection conn = connect();PreparedStatement ps = conn.prepareStatement(sql)){
ps.setLong(1,id);
ps.executeUpdate();
}catch (SQLException e){
e.printStackTrace();
}
}
private static String queryBuilder(String type,String table, String[] header, String[] values){
String sql;
StringBuilder sb = new StringBuilder();
switch (type) {
case "exists" -> {
sb = new StringBuilder("SELECT (count(*) > 0) as found FROM ");
sb.append(table);
sb.append(" WHERE ");
sb.append(header[0]);
sb.append(" LIKE '");
sb.append(values[0]);
sb.append("'");
for (int i = 1; i < header.length; i++) {
sb.append(" AND ");
sb.append(header[i]);
sb.append(" LIKE '");
sb.append(values[i]);
sb.append("'");
}
}
case "selectMatch" -> {
sb = new StringBuilder("SELECT * FROM ");
sb.append(table);
sb.append(" WHERE ");
sb.append(header[0]);
sb.append(" LIKE '");
sb.append(values[0]);
sb.append("'");
for (int i = 1; i < header.length; i++) {
sb.append(" AND ");
sb.append(header[i]);
sb.append(" LIKE '");
sb.append(values[i]);
sb.append("'");
}
}
case "insert" -> {
sb = new StringBuilder("INSERT OR IGNORE INTO ");
sb.append(table);
sb.append(" (");
sb.append(header[0]);
for (int i = 1; i < header.length; i++) {
sb.append(",");
sb.append(header[i]);
}
sb.append(") VALUES('");
sb.append(values[0]);
sb.append("'");
for (int i = 1; i < values.length; i++) {
sb.append(",'");
sb.append(values[i]);
sb.append("'");
}
sb.append(");");
}
case "count" -> {
sb = new StringBuilder("SELECT COUNT(*) FROM ");
sb.append(table);
sb.append(" WHERE ");
sb.append(header[0]);
sb.append(" = ");
sb.append(values[0]);
for(int i = 1; i < header.length; i++){
sb.append(" AND ");
sb.append(header[i]);
sb.append(" = ");
sb.append(values[i]);
}
}
case "update" -> {
sb = new StringBuilder("UPDATE ");
sb.append(table);
sb.append(" SET ");
sb.append(header[1]);
sb.append(" = ");
sb.append(values[1]);
for(int i = 2; i < header.length; i++){
sb.append(", ");
sb.append(header[i]);
sb.append(" = ");
sb.append(values[i]);
}
sb.append(" WHERE ");
sb.append(header[0]);
sb.append(" = ");
sb.append(values[0]);
}
}
sql = sb.toString();
return sql;
}
/**
* returns a list of all entries
* @param table the table you want
* @return a list of all entries as String with the fields separated by ":"
*/
protected static List<String> getTable(String table){
List<String> data = new ArrayList<>();
StringBuilder sb;
try(Connection conn = connect()) {
String sql = "SELECT * FROM " + table;
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
int count = rsmd.getColumnCount();
while (rs.next()){
sb = new StringBuilder();
sb.append(rs.getString(1));
for(int i = 2; i <= count; i++){
sb.append(":");
sb.append(rs.getString(i));
}
data.add(sb.toString());
}
}catch (SQLException e){
return new ArrayList<>();
}
return data;
}
/**
* issues a select query on the database for the given table and the given values checked with LIKE
* @param table the table you want the data from
* @param header header for the WHERE portion, order should match with values
* @param values values for the WHERE portion, order should match with header
* @return a list of the matching data as String separated by ":"
*/
protected static List<String> select(String table,String[] header, String[] values){
List<String> data = new ArrayList<>();
StringBuilder sb;
String sql = queryBuilder("selectMatch",table,header,values);
try(Connection conn = connect()) {
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
int count = rsmd.getColumnCount();
while (rs.next()){
sb = new StringBuilder();
sb.append(rs.getString(1));
for(int i = 2; i <= count; i++){
sb.append(":");
sb.append(rs.getString(i));
}
data.add(sb.toString());
}
}catch (SQLException e){
e.printStackTrace();
return data;
}
return data;
}
/**
* returns the entry from table with the given id
* @param table the table you want the entry from
* @param id the id of the entry you want
* @return a list of String separated by ":"
*/
protected static List<String> getEntryById(String table, long id){
List<String> data = new ArrayList<>();
StringBuilder sb;
String sql = "SELECT * FROM " + table + " WHERE id = ?;";
try (Connection conn = connect()) {
PreparedStatement ps = conn.prepareStatement(sql);
ps.setLong(1,id);
ResultSet rs = ps.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
int count = rsmd.getColumnCount();
while (rs.next()){
sb = new StringBuilder();
sb.append(rs.getString(1));
for(int i = 2; i <= count; i++){
sb.append(":");
sb.append(rs.getString(i));
}
data.add(sb.toString());
}
} catch (SQLException e) {
e.printStackTrace();
return data;
}
return data;
}
/**
* counts the number of matching entries
* @param table the table you want to count
* @param header the properties you want to count on
* @param values the values for the properties
* @return the number of found rows
*/
protected static int count(String table,String[] header,String[] values){
String sql = queryBuilder("count",table,header,values);
try(Connection conn = connect()) {
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
return rs.getInt(1);
}catch (SQLException e){
return -1;
}
}
/**
* updates an entry in the database
* @param table the table you want to update
* @param header [0] is used as WHERE, everything else in SET
* @param values [0] is used as WHERE, everything else in SET
* @return number of rows affected or -1 on error
*/
protected static int update(String table,String[] header,String[] values){
try(Connection conn = connect()) {
String sql = queryBuilder("update",table,header,values);
PreparedStatement ps = conn.prepareStatement(sql);
return ps.executeUpdate();
}catch (SQLException e){
return -1;
}
}
}