From 3f55f66e65c36ad5655d2118995011c65587d823 Mon Sep 17 00:00:00 2001
From: AdrianBalunan
Date: Wed, 11 Mar 2026 15:11:22 +0100
Subject: [PATCH] Feat: DAO data acsess object(s) will help SETTING new data to
database
---
.../sytemutvikling/team6/DAO/CharityDAO.java | 273 ++++++++++++++++++
.../sytemutvikling/team6/DAO/DonationDAO.java | 4 +
2 files changed, 277 insertions(+)
create mode 100644 helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/DAO/CharityDAO.java
create mode 100644 helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/DAO/DonationDAO.java
diff --git a/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/DAO/CharityDAO.java b/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/DAO/CharityDAO.java
new file mode 100644
index 0000000..810eca1
--- /dev/null
+++ b/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/DAO/CharityDAO.java
@@ -0,0 +1,273 @@
+package ntnu.sytemutvikling.team6.DAO;
+
+import ntnu.sytemutvikling.team6.scraper.APICharityData;
+
+import java.sql.*;
+import java.util.List;
+
+/**
+ * Manages the charity
+ *
+ * This class is responsible for establishing connections using environment variables
+ * and maintaining the {@code charities} table based on data retrieved from the IK API.
+ *
+ */
+
+public class CharityDAO {
+
+import APICharityData;
+
+import java.sql.*;
+import java.util.List;
+
+
+
+ public class DatabaseManager {
+ private final String databaseURL;
+ private final String username;
+ private final String password;
+
+ /**
+ Constructs a new {@code DatabaseManager} using database credentials
+ * retrieved from system environment variables.
+ *
+ * Required environment variables:
+ *
+ * - {@code HMH_DB_URL}
+ * - {@code HMH_DB_USERNAME}
+ * - {@code HMH_DB_PASSWORD}
+ *
+ *
+ *
+ * @throws IllegalStateException if either databaseURL, username, or password is {@code null} or blank
+ */
+
+ // Values stored in system environment variables for security (using ntnu's phpmyadmin for this project)
+ public DatabaseManager() {
+ this.databaseURL = System.getenv("HMH_DB_URL");
+ this.username = System.getenv("HMH_DB_USERNAME");
+ this.password = System.getenv("HMH_DB_PASSWORD");
+
+ if (this.databaseURL == null || this.databaseURL.isBlank()) {
+ throw new IllegalStateException("Database environment variable URL has not been set");
+ }
+
+ if (this.username == null || this.username.isBlank()) {
+ throw new IllegalStateException("Username environment variable has not been set");
+ }
+
+ if (this.password == null || this.password.isBlank()) {
+ throw new IllegalStateException("Password environment variable has not been set");
+ }
+ }
+
+ /**
+ * Constructs a new {@code DatabaseManager} using database credentials
+ *
+ * Used primarily for JUnit tests. Production should use the constructor
+ * using environment variables.
+ *
+ *
+ * @param databaseURL the url to the database
+ * @param username the username used to log in to the database
+ * @param password the password used to log in to the database
+ * @throws IllegalArgumentException if databaseURL, username, or password is
+ * {@code null} or blank
+ */
+
+ public DatabaseManager(String databaseURL, String username, String password) {
+ this.databaseURL = databaseURL;
+ this.username = username;
+ this.password = password;
+
+ if (this.databaseURL == null || this.databaseURL.isBlank()) {
+ throw new IllegalArgumentException("Database environment variable URL has not been set");
+ }
+
+ if (this.username == null || this.username.isBlank()) {
+ throw new IllegalArgumentException("Username environment variable has not been set");
+ }
+
+ if (this.password == null || this.password.isBlank()) {
+ throw new IllegalArgumentException("Password environment variable has not been set");
+ }
+ }
+
+ /**
+ * Creates the {@code charities} table if it does not already exist.
+ *
+ * The table structure is based on fields from {@link APICharityData}.
+ *
+ * @throws RuntimeException if a {@link SQLException} occurs while creating the table
+ */
+
+ public void createTables() {
+ String sql_query = """
+ -- MySQL Workbench Forward Engineering
+
+ SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
+ SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
+ SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
+
+ -- -----------------------------------------------------
+ -- Schema HelpMeHelp
+ -- -----------------------------------------------------
+
+ -- -----------------------------------------------------
+ -- Schema HelpMeHelp
+ -- -----------------------------------------------------
+ --CREATE SCHEMA IF NOT EXISTS `HelpMeHelp` DEFAULT CHARACTER SET utf8 ;
+ --USE `HelpMeHelp` ;
+ USE apbaluna;
+
+ -- -----------------------------------------------------
+ -- Table `HelpMeHelp`.`Charities`
+ -- -----------------------------------------------------
+ CREATE TABLE IF NOT EXISTS `HelpMeHelp`.`Charities` (
+ `UUID` CHAR(36) NOT NULL,
+ `charity_name` VARCHAR(255) NOT NULL,
+ `charity_description` VARCHAR(255) NOT NULL,
+ `isVerified` TINYINT NOT NULL,
+ `category` VARCHAR(45) NOT NULL,
+ PRIMARY KEY (`UUID`))
+ ENGINE = InnoDB;
+
+
+ -- -----------------------------------------------------
+ -- Table `HelpMeHelp`.`Donations`
+ -- -----------------------------------------------------
+ CREATE TABLE IF NOT EXISTS `HelpMeHelp`.`Donations` (
+ `UUID` CHAR(36) NOT NULL,
+ `amount` DECIMAL NOT NULL,
+ `date` DATE NOT NULL,
+ `Charities_UUID` CHAR(36) NOT NULL,
+ PRIMARY KEY (`UUID`),
+ INDEX `fk_Donations_Charities_idx` (`Charities_UUID` ASC) VISIBLE,
+ CONSTRAINT `fk_Donations_Charities`
+ FOREIGN KEY (`Charities_UUID`)
+ REFERENCES `HelpMeHelp`.`Charities` (`UUID`)
+ ON DELETE NO ACTION
+ ON UPDATE NO ACTION)
+ ENGINE = InnoDB;
+
+
+ SET SQL_MODE=@OLD_SQL_MODE;
+ SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
+ SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
+
+ """;
+
+ try (Connection conn = DriverManager.getConnection(databaseURL, username, password);
+ Statement s = conn.createStatement()) {
+
+ s.execute(sql_query);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ throw new RuntimeException("Error creating table.");
+ }
+ }
+
+ /**
+ * Synchronizes the {@code charities} table with the provided list of APICharityData.
+ *
+ * Summary of function:
+ *
+ * - Inserts new records
+ * - Updates existing records using {@code ON DUPLICATE KEY UPDATE}
+ * - Removes database records that are not present in the provided list
+ *
+ * A temporary table is used to determine which records should be deleted.
+ *
+ *
+ * @param charities a list of ApiCharityDaya objects
+ * @throws RuntimeException if a {@link SQLException} occurs during database synchronization
+ */
+
+ public void updateCharities(List charities) {
+ Connection conn = null;
+ try {
+ conn = DriverManager.getConnection(databaseURL, username, password);
+ conn.setAutoCommit(false);
+ // Inserts objects values into charities
+ String sql_query = """
+ INSERT INTO charities (org_number, name, status, url, is_pre_approved)
+ VALUES (?, ?, ?, ?, ?)
+ ON DUPLICATE KEY UPDATE
+ name = VALUES(name),
+ status = VALUES(status),
+ url = VALUES(url),
+ is_pre_approved = VALUES(is_pre_approved)
+ """;
+
+ try (PreparedStatement s = conn.prepareStatement(sql_query)) {
+ for (APICharityData charity : charities) {
+ s.setString(1, charity.getOrg_number().replaceAll("\\s", ""));
+ s.setString(2, charity.getName());
+ s.setString(3, charity.getStatus());
+ s.setString(4, charity.getUrl());
+ s.setBoolean(5, charity.getIs_pre_approved());
+
+ s.addBatch();
+ }
+ s.executeBatch();
+ }
+
+
+ // Temporary table for parity check
+ sql_query = "CREATE TEMPORARY TABLE temp (org_number VARCHAR(100) PRIMARY KEY)";
+ try (PreparedStatement temp_create = conn.prepareStatement(sql_query)) {
+ temp_create.execute();
+ }
+
+ String sql_update_temp_table = "INSERT INTO temp (org_number) VALUES (?)";
+ try (PreparedStatement temp_update = conn.prepareStatement(sql_update_temp_table)) {
+ for (APICharityData charity : charities) {
+ temp_update.setString(1, charity.getOrg_number().replaceAll("\\s", ""));
+ temp_update.addBatch();
+ }
+ temp_update.executeBatch();
+ }
+
+
+
+ // Removes records not found in the list from charities table
+ sql_query = """
+ DELETE FROM charities c
+ WHERE NOT EXISTS (
+ SELECT 1
+ FROM temp t
+ WHERE c.org_number = t.org_number
+ )
+ """;
+
+ try (PreparedStatement delete_old_records = conn.prepareStatement(sql_query)){
+ delete_old_records.execute();
+ }
+
+ conn.commit();
+ } catch (SQLException e) {
+
+ if (conn != null) {
+ try {
+ conn.rollback();
+ } catch (SQLException ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ e.printStackTrace();
+ throw new RuntimeException("ERROR: Something went wrong during updating charities table.");
+ } finally {
+ if (conn != null) {
+ try {
+ conn.setAutoCommit(true);
+ conn.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ }
+ }
+}
diff --git a/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/DAO/DonationDAO.java b/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/DAO/DonationDAO.java
new file mode 100644
index 0000000..b902276
--- /dev/null
+++ b/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/DAO/DonationDAO.java
@@ -0,0 +1,4 @@
+package ntnu.sytemutvikling.team6.DAO;
+
+public class DonationDAO {
+}