From 7e871f824c4a85cca5f77382ed0f31dd17ccfcb7 Mon Sep 17 00:00:00 2001 From: jeffcheasey88 Date: Sun, 26 Jan 2025 11:01:29 +0100 Subject: [PATCH] Adding system to dynamicly update SQL's statements without restarting the app --- src/dev/peerat/backend/Configuration.java | 6 + src/dev/peerat/backend/Main.java | 3 +- .../repository/DatabaseAdminRepository.java | 1 - .../repository/DatabaseRepository.java | 111 +++++++++++++++++- 4 files changed, 118 insertions(+), 3 deletions(-) diff --git a/src/dev/peerat/backend/Configuration.java b/src/dev/peerat/backend/Configuration.java index 562f010..1c3bc52 100644 --- a/src/dev/peerat/backend/Configuration.java +++ b/src/dev/peerat/backend/Configuration.java @@ -44,6 +44,8 @@ public class Configuration { private String git_token; private String jwt_key; + + private String sql_folder; private File _file; @@ -222,4 +224,8 @@ public class Configuration { public void setJwtKey(String key){ this.jwt_key = key; } + + public String getSqlFolder(){ + return this.sql_folder; + } } \ No newline at end of file diff --git a/src/dev/peerat/backend/Main.java b/src/dev/peerat/backend/Main.java index d66275e..efaa6f9 100644 --- a/src/dev/peerat/backend/Main.java +++ b/src/dev/peerat/backend/Main.java @@ -12,6 +12,7 @@ import dev.peerat.backend.bonus.extract.RouteExtracter; import dev.peerat.backend.model.Group; import dev.peerat.backend.model.PeerAtUser; import dev.peerat.backend.repository.ConnectionManager; +import dev.peerat.backend.repository.DatabaseBadgeRepository; import dev.peerat.backend.repository.DatabaseRepository; import dev.peerat.framework.Context; import dev.peerat.framework.DependencyInjector; @@ -39,7 +40,7 @@ public class Main{ config.load(); Class.forName("com.mysql.cj.jdbc.Driver"); - + DatabaseRepository repo = new DatabaseRepository(new ConnectionManager(config), config); Router router = new Router() .activeReOrdering(). diff --git a/src/dev/peerat/backend/repository/DatabaseAdminRepository.java b/src/dev/peerat/backend/repository/DatabaseAdminRepository.java index 52632d2..a655e26 100644 --- a/src/dev/peerat/backend/repository/DatabaseAdminRepository.java +++ b/src/dev/peerat/backend/repository/DatabaseAdminRepository.java @@ -1,6 +1,5 @@ package dev.peerat.backend.repository; -import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; diff --git a/src/dev/peerat/backend/repository/DatabaseRepository.java b/src/dev/peerat/backend/repository/DatabaseRepository.java index 132ef14..48faa96 100644 --- a/src/dev/peerat/backend/repository/DatabaseRepository.java +++ b/src/dev/peerat/backend/repository/DatabaseRepository.java @@ -1,5 +1,19 @@ package dev.peerat.backend.repository; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.reflect.Field; +import java.nio.file.FileSystems; +import java.nio.file.Path; +import java.nio.file.StandardWatchEventKinds; +import java.nio.file.WatchEvent; +import java.nio.file.WatchKey; +import java.nio.file.WatchService; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -25,7 +39,7 @@ public class DatabaseRepository extends BaseDatabaseQuery{ private DatabaseLeaderboardRepository leaderboardRepo; private DatabasePlayerRepository playerRepo; - public DatabaseRepository(ConnectionManager con, Configuration config) { + public DatabaseRepository(ConnectionManager con, Configuration config) throws Exception { super(con); this.config = config; @@ -38,6 +52,101 @@ public class DatabaseRepository extends BaseDatabaseQuery{ this.groupRepo = new DatabaseGroupRepository(con, config); this.leaderboardRepo = new DatabaseLeaderboardRepository(con, config); this.playerRepo = new DatabasePlayerRepository(con, config); + + loadConfig(config); + } + + private void loadConfig(Configuration config) throws Exception{ + String name = DatabaseRepository.class.getPackage().getName(); + InputStream stream = ClassLoader.getSystemClassLoader().getResourceAsStream(name.replace(".", "/")); + File folder = new File(config.getSqlFolder()); + try{ + BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); + String line; + while((line = reader.readLine()) != null){ + if(line.endsWith(".class")){ + Class clazz = Class.forName(name+"."+line.substring(0, line.length()-6)); + if(BaseDatabaseQuery.class.isAssignableFrom(clazz)){ + for(Class subClazz : clazz.getDeclaredClasses()){ + if(subClazz.isEnum()){ + configure(subClazz, folder); + } + } + } + continue; + } + } + reader.close(); + }catch(Exception e){ + System.err.println("Failed to read "+name); + e.printStackTrace(); + } + new Thread(() -> { + try{ + WatchService watchService = FileSystems.getDefault().newWatchService(); + Path path = folder.toPath(); + path.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY); + while (true) { + WatchKey key = watchService.take(); + for(WatchEvent event : key.pollEvents()){ + Path edited = (Path) event.context(); + String targetClazz = edited.toFile().getName().split("\\.")[0]; + Class clazz = Class.forName(name+"."+targetClazz); + if(BaseDatabaseQuery.class.isAssignableFrom(clazz)){ + for(Class subClazz : clazz.getDeclaredClasses()){ + if(subClazz.isEnum()){ + bind(subClazz, new File(folder, edited.toFile().getName())); + } + } + } + } + key.reset(); + } + }catch(Exception ex){ + ex.printStackTrace(); + } + }).start(); + } + + private void configure(Class clazz, File folder) throws Exception{ + String name = clazz.getName().split("\\$")[0]; + String[] split = name.split("\\."); + File file = new File(folder, split[split.length-1]+".txt"); + if(file.exists()){ + bind(clazz, file); + }else{ + File parent = file.getParentFile(); + if(!parent.exists()) parent.mkdirs(); + file.createNewFile(); + BufferedWriter writer = new BufferedWriter(new FileWriter(file)); + for(Object obj : clazz.getEnumConstants()){ + Enum instance = (Enum) obj; + writer.write(instance.name()+"="+instance.toString().replace("\n", " ").replace("\r", " ")+"\n"); + } + writer.flush(); + writer.close(); + } + } + + private void bind(Class clazz, File file) throws Exception{ + Map map = new HashMap<>(); + BufferedReader reader = new BufferedReader(new FileReader(file)); + String line; + while((line = reader.readLine()) != null){ + int index = line.indexOf('='); + String key = line.substring(0, index); + String value = line.substring(index+1); + map.put(key, value); + } + reader.close(); + + for(Object obj : clazz.getEnumConstants()){ + Enum instance = (Enum) obj; + String value = map.get(instance.name()); + Field field = obj.getClass().getDeclaredField("request"); + field.setAccessible(true); + field.set(instance, value); + } } public DatabasePuzzleRepository getPuzzleRepository(){