package jesse.keeblarcraft.ConfigMgr; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import jesse.keeblarcraft.ConfigMgr.SQLTypeSupport.VALID_SQL_TYPE; import jesse.keeblarcraft.Utils.CommonStructures.Pair; public class SQLConfig { private static SQLConfig static_inst; private String dbName; private String dbUser; private String dbPass; private String dbAddr; private Boolean connected = false; private Connection conn = null; // Actual connection object private enum SQL_RUN_TYPE { GENERAL, QUERY, UPDATE } // Direct return object in relation to the SQL_RUN_TYPE of the SQL command that was used. Only one will // be filled out properly for what you run - the other values will be null and not cleared! private class SQLRunReturn { Boolean generalRet; ResultSet queryReturn; Integer updateReturn; } public static SQLConfig GetInstance() { if (static_inst == null) { static_inst = new SQLConfig(); } return static_inst; } public SQLConfig() { connected = false; try { // According to some random online tutorial; this loads the driver! Class.forName("com.mysql.cj.jdbc.Driver"); connected = true; } catch (Exception e) { System.out.println("Could not find the proper SQL JDBC Drivers. Cannot connect to SQL Config"); e.printStackTrace(); } if (connected) { try { dbName = GeneralConfig.GetInstance().GetSQLDatabase(); dbUser = GeneralConfig.GetInstance().GetSQLUsername(); dbPass = GeneralConfig.GetInstance().GetSQLPassword(); dbAddr = "jdbc:mysql://" + GeneralConfig.GetInstance().GetSQLAddress() + "/" + dbName; conn = DriverManager.getConnection(dbAddr, dbUser, dbPass); } catch (SQLException e) {} } } private SQLRunReturn RunCommand(String sqlCommand, SQL_RUN_TYPE type) { SQLRunReturn sqlData = new SQLRunReturn(); // If conn is null; we may need to reconnect before running the command if (conn == null) { Connect(); } if (conn != null) { try { Statement statement = conn.createStatement(); switch(type) { case GENERAL: sqlData.generalRet = statement.execute(sqlCommand); break; case QUERY: sqlData.queryReturn = statement.executeQuery(sqlCommand); break; case UPDATE: sqlData.updateReturn = statement.executeUpdate(sqlCommand); break; } } catch (SQLException e) { System.out.println(e.getSQLState()); } } return sqlData; } // Re-attempt the connection public Boolean Connect() { if (conn != null) { try { conn.close(); } catch (Exception e) {} } Boolean success = false; try { conn = DriverManager.getConnection(dbAddr, dbUser, dbPass); success = true; } catch (Exception e) {} return success; } public Boolean IsConnected() { return conn != null && this.connected; } // The case is converted to upper case automatically to be case insensitive public Boolean DoesTableExist(String name) { boolean tableExists = false; if (conn != null) { try (ResultSet rs = conn.getMetaData().getTables(null, null, name, null)) { while (rs.next()) { String tName = rs.getString("TABLE_NAME"); if (tName != null && tName.equals(name)) { tableExists = true; break; } } } catch (SQLException e) {} } return tableExists; } public Boolean MakeNonNullable(String table, String columnName) { return false; } public Integer AddPrimaryKey(String tableName, String primaryKeyColumn) { SQLRunReturn success = new SQLRunReturn(); if (DoesTableExist(tableName)) { String sqlCmd = "ALTER TABLE " + tableName + " ADD PRIMARY KEY (" + primaryKeyColumn + ");"; success = RunCommand(sqlCmd, SQL_RUN_TYPE.UPDATE); } return success.updateReturn; } public Integer AddForeignKey(String primaryTableName, String primaryColumnName, String foreignTableName, String foreignKeyColumn) { SQLRunReturn success = new SQLRunReturn(); Boolean primaryTableExists = DoesTableExist(primaryTableName); Boolean foreignTableExists = DoesTableExist(foreignTableName); if (primaryTableExists && foreignTableExists) { String sqlCmd = "ALTER TABLE " + primaryTableName + " ADD FOREIGN KEY (" + primaryColumnName + ") REFERENCES " + foreignTableName + " (" + foreignKeyColumn + ")"; success = RunCommand(sqlCmd, SQL_RUN_TYPE.UPDATE); } return success.updateReturn; } // Might fix heap pollution decay in future with enum types or something. For now we assume the user isn't horrifically stupid and will give a SQL-able type public Boolean CreateTable(String tableName, Pair... columnPairs) { Boolean success = false; if (conn != null && !DoesTableExist(tableName.toUpperCase())) { String sqlCommand = "CREATE TABLE " + tableName.toUpperCase() + "("; for (Pair colPair : columnPairs) { sqlCommand = sqlCommand + " " + colPair.GetKey() + " " + SQLTypeSupport.GetSqlStrForType(colPair.GetValue()) + ","; } // Strip the leading comma and append the ending ');' on the SQL statement sqlCommand = sqlCommand.substring(0, sqlCommand.length() - 1) + ");"; SQLRunReturn rs = RunCommand(sqlCommand, SQL_RUN_TYPE.GENERAL); try { while (rs.queryReturn.next()) { } } catch (Exception e) {} } return success; } }