Adding system to dynamicly update SQL's statements without restarting the app

This commit is contained in:
jeffcheasey88 2025-01-26 11:01:29 +01:00
parent 0bfba6d99c
commit 7e871f824c
4 changed files with 118 additions and 3 deletions

View file

@ -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;
}
}

View file

@ -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<PeerAtUser> router = new Router<PeerAtUser>()
.activeReOrdering().

View file

@ -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;

View file

@ -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<String, String> 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(){