From 6c509f05e89752457d24857b75ead17402065e86 Mon Sep 17 00:00:00 2001 From: AdrianBalunan Date: Wed, 11 Mar 2026 15:09:55 +0100 Subject: [PATCH] Feat: APIScraper can will update the database --- .../team6/scraper/APICharityScraper.java | 111 +++++++++++++++++- 1 file changed, 109 insertions(+), 2 deletions(-) diff --git a/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/scraper/APICharityScraper.java b/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/scraper/APICharityScraper.java index 72319ab..db2482f 100644 --- a/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/scraper/APICharityScraper.java +++ b/helpmehelpapplication/src/main/java/ntnu/sytemutvikling/team6/scraper/APICharityScraper.java @@ -1,24 +1,29 @@ package ntnu.sytemutvikling.team6.scraper; import com.google.gson.Gson; -import ntnu.sytemutvikling.team6.DAO.APICharityData; +import ntnu.sytemutvikling.team6.database.DatabaseConnection; import java.io.IOException; import java.net.*; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * Fetches JSON information from the IK API and parses the JSON into a list of {@link APICharityData} objects. + * AND can update the database. */ public class APICharityScraper { private final HttpClient client; private final HttpRequest request; + private final DatabaseConnection connection; /** * Constructs a new APICharityScraper object. @@ -32,7 +37,8 @@ public APICharityScraper(HttpClient client) throws URISyntaxException { .uri(new URI("https://app.innsamlingskontrollen.no/api/public/v1/all")) .GET() .build(); - } + this.connection = new DatabaseConnection(); + } /** * Checks if the http request returns an 'OK' response. @@ -89,5 +95,106 @@ public List parseJSON(String JSONData) { .filter(c-> !"obs".equalsIgnoreCase(c.getStatus())) .toList(); } + /** + * Synchronizes the {@code charities} table with the provided list of APICharityData. + *

+ * Summary of function: + *

+ * 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 = connection.getMySqlConnection(); + 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(); + } + } + } + } }