SteamWar/SpigotCore
Archiviert
13
0

Merge pull request 'New SQL API + SchemByUserAndType speedup' (#115) from schemSpeedup into master

Reviewed-on: #115
Reviewed-by: YoyoNow <jwsteam@nidido.de>
Dieser Commit ist enthalten in:
Lixfel 2021-09-17 07:46:02 +02:00
Commit fa3e935b90
3 geänderte Dateien mit 112 neuen und 35 gelöschten Zeilen

Datei anzeigen

@ -71,7 +71,7 @@ public class Core extends JavaPlugin{
@Override @Override
public void onDisable(){ public void onDisable(){
SQL.closeConnection(); SQL.close();
} }
public static Core getInstance() { public static Core getInstance() {

Datei anzeigen

@ -24,18 +24,18 @@ import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File; import java.io.File;
import java.sql.*; import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
public class SQL { public class SQL {
private SQL(){} private SQL(){}
private static final String host;
private static final String port;
private static final String database;
private static final String user;
private static final String password;
private static Connection con; private static Connection con;
private static String url;
private static String user;
private static String password;
static{ static{
File file = new File(Core.getInstance().getDataFolder(), "MySQL.yml"); File file = new File(Core.getInstance().getDataFolder(), "MySQL.yml");
@ -44,20 +44,47 @@ public class SQL {
if(!file.exists()) if(!file.exists())
throw new SecurityException("SQL-ConfigFile not found!"); throw new SecurityException("SQL-ConfigFile not found!");
host = config.getString("HOST"); url = "jdbc:mysql://" + config.getString("HOST") + ":" + config.getString("PORT") + "/" + config.getString("DATABASE");
port = config.getString("PORT");
database = config.getString("DATABASE");
user = config.getString("USER"); user = config.getString("USER");
password = config.getString("PASSWORD"); password = config.getString("PASSWORD");
connect(); connect();
} }
public static void closeConnection() { private static void connect() {
try {
con = DriverManager.getConnection(url + "?autoreconnect=true", user, password);
} catch (SQLException e) {
throw new SecurityException("Could not start SQL connection", e);
}
}
public static void close() {
for (Statement statement : Statement.statements) {
try {
statement.st.close();
} catch (SQLException e) {
Core.getInstance().getLogger().log(Level.INFO, "Could not close statement", e);
}
}
try { try {
con.close(); con.close();
}catch (SQLException e) { } catch (SQLException e) {
throw new SecurityException("Could not close connection", e); Core.getInstance().getLogger().log(Level.WARNING, "Could not close SQL-Connection", e);
}
}
private static void reset(SQLException e) {
Core.getInstance().getLogger().log(Level.WARNING, "SQL Exception thrown", e);
close();
connect();
try {
for (Statement statement : Statement.statements) {
statement.init();
}
} catch (SQLException ex) {
throw new SecurityException("Could not reprepare SQL Statements", ex);
} }
} }
@ -65,7 +92,7 @@ public class SQL {
try { try {
prepare(qry, objects).executeUpdate(); prepare(qry, objects).executeUpdate();
} catch (SQLException e) { } catch (SQLException e) {
reconnect(); reset(e);
try { try {
prepare(qry, objects).executeUpdate(); prepare(qry, objects).executeUpdate();
} catch (SQLException ex) { } catch (SQLException ex) {
@ -78,7 +105,7 @@ public class SQL {
try { try {
return prepare(qry, objects).executeQuery(); return prepare(qry, objects).executeQuery();
} catch (SQLException e) { } catch (SQLException e) {
reconnect(); reset(e);
try { try {
return prepare(qry, objects).executeQuery(); return prepare(qry, objects).executeQuery();
} catch (SQLException ex) { } catch (SQLException ex) {
@ -91,7 +118,7 @@ public class SQL {
try { try {
return con.createBlob(); return con.createBlob();
} catch (SQLException e) { } catch (SQLException e) {
reconnect(); reset(e);
try { try {
return con.createBlob(); return con.createBlob();
} catch (SQLException ex) { } catch (SQLException ex) {
@ -108,18 +135,66 @@ public class SQL {
return st; return st;
} }
private static void connect() { public static class Statement {
try { private static final List<Statement> statements = new ArrayList<>();
con = DriverManager.getConnection("jdbc:mysql://" + host + ":" + port + "/" + database + "?autoreconnect=true", user, password);
if(con.isClosed()) private final String sql;
throw new SQLException("Could not connect to database!"); private PreparedStatement st;
}catch (SQLException e) {
throw new SecurityException("No connection to database.", e); Statement(String sql) {
this.sql = sql;
statements.add(this);
try {
init();
} catch (SQLException e) {
reset(e);
}
}
private synchronized void init() throws SQLException {
st = con.prepareStatement(sql);
}
<T> T select(ResultSetUser<T> user, Object... objects) {
return prepare(() -> {
ResultSet rs = st.executeQuery();
T result = user.use(rs);
rs.close();
return result;
}, objects);
}
void update(Object... objects) {
prepare(st::executeUpdate, objects);
}
private synchronized <T> T prepare(SQLRunnable<T> runnable, Object... objects) {
try {
setObjects(objects);
return runnable.run();
} catch (SQLException e) {
reset(e);
try {
setObjects(objects);
return runnable.run();
} catch (SQLException ex) {
throw new SecurityException("Could not execute SQL statement", ex);
}
}
}
private void setObjects(Object... objects) throws SQLException {
for (int i = 0; i < objects.length; i++) {
st.setObject(i + 1, objects[i]);
}
}
interface ResultSetUser<T> {
T use(ResultSet rs) throws SQLException;
}
private interface SQLRunnable<T> {
T run() throws SQLException;
} }
} }
private static void reconnect(){
closeConnection();
connect();
}
} }

Datei anzeigen

@ -35,6 +35,8 @@ import java.util.zip.GZIPInputStream;
public class Schematic { public class Schematic {
private static final SQL.Statement getSchemsOfType = new SQL.Statement("SELECT DISTINCT s.SchemID, s.SchemName, s.SchemOwner, s.Item, s.SchemType, s.Rank, s.SchemFormat FROM Schematic s LEFT JOIN SchemMember sm ON sm.SchemName = s.SchemName AND sm.SchemOwner = s.SchemOwner WHERE s.SchemType = ? AND (s.SchemOwner = ? OR sm.Member = ?) ORDER BY s.SchemName");
private final int schemID; private final int schemID;
private final String schemName; private final String schemName;
private final int schemOwner; private final int schemOwner;
@ -118,12 +120,12 @@ public class Schematic {
} }
public static List<Schematic> getSchemsOfType(int schemOwner, SchematicType schemType){ public static List<Schematic> getSchemsOfType(int schemOwner, SchematicType schemType){
//Unsauber, dafür auch geaddede Schematics dabei return getSchemsOfType.select(rs -> {
List<Schematic> schems = getSchemsAccessibleByUser(schemOwner); List<Schematic> schematics = new ArrayList<>();
for(int i = schems.size()-1; i >= 0; i--) while(rs.next())
if(!schems.get(i).getSchemType().equals(schemType)) schematics.add(new Schematic(rs));
schems.remove(i); return schematics;
return schems; }, schemType.toDB(), schemOwner, schemOwner);
} }
public static List<Schematic> getAllSchemsOfType(SchematicType schemType){ public static List<Schematic> getAllSchemsOfType(SchematicType schemType){