2025-01-03 04:05:16 +00:00
package jesse.keeblarcraft.ConfigMgr ;
import java.sql.Connection ;
import java.sql.DriverManager ;
import java.sql.ResultSet ;
import java.sql.SQLException ;
import java.sql.Statement ;
2025-01-15 03:56:38 +00:00
import jesse.keeblarcraft.ConfigMgr.SQLTypeSupport.VALID_SQL_TYPE ;
2025-01-10 02:44:17 +00:00
import jesse.keeblarcraft.Utils.CommonStructures.Pair ;
2025-01-03 04:05:16 +00:00
public class SQLConfig {
private static SQLConfig static_inst ;
2025-01-10 02:44:17 +00:00
private String dbName ;
private String dbUser ;
private String dbPass ;
private String dbAddr ;
private Boolean connected = false ;
private Connection conn = null ; // Actual connection object
2025-01-03 04:05:16 +00:00
2025-01-15 03:56:38 +00:00
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 ;
}
2025-01-03 04:05:16 +00:00
public static SQLConfig GetInstance ( ) {
if ( static_inst = = null ) {
static_inst = new SQLConfig ( ) ;
}
return static_inst ;
}
public SQLConfig ( ) {
2025-01-10 02:44:17 +00:00
connected = false ;
2025-01-03 04:05:16 +00:00
try {
// According to some random online tutorial; this loads the driver!
Class . forName ( " com.mysql.cj.jdbc.Driver " ) ;
2025-01-10 02:44:17 +00:00
connected = true ;
2025-01-03 04:05:16 +00:00
} catch ( Exception e ) {
System . out . println ( " Could not find the proper SQL JDBC Drivers. Cannot connect to SQL Config " ) ;
e . printStackTrace ( ) ;
}
2025-01-10 02:44:17 +00:00
if ( connected ) {
2025-01-03 04:05:16 +00:00
try {
2025-01-10 02:44:17 +00:00
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 ) ;
2025-01-03 04:05:16 +00:00
} catch ( SQLException e ) { }
}
}
2025-01-10 02:44:17 +00:00
2025-01-15 03:56:38 +00:00
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 ( ) ;
}
2025-01-10 02:44:17 +00:00
if ( conn ! = null ) {
try {
Statement statement = conn . createStatement ( ) ;
2025-01-15 03:56:38 +00:00
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 ( ) ) ;
}
2025-01-10 02:44:17 +00:00
}
2025-01-15 03:56:38 +00:00
return sqlData ;
2025-01-10 02:44:17 +00:00
}
// 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 ;
}
2025-01-15 03:56:38 +00:00
// The case is converted to upper case automatically to be case insensitive
public Boolean DoesTableExist ( String name ) {
2025-01-10 02:44:17 +00:00
boolean tableExists = false ;
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 ;
}
2025-01-15 03:56:38 +00:00
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 ;
}
2025-01-10 02:44:17 +00:00
// 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
2025-01-15 03:56:38 +00:00
public Boolean CreateTable ( String tableName , Pair < String , VALID_SQL_TYPE > . . . columnPairs ) {
2025-01-10 02:44:17 +00:00
Boolean success = false ;
2025-01-15 03:56:38 +00:00
if ( ! DoesTableExist ( tableName . toUpperCase ( ) ) ) {
2025-01-10 02:44:17 +00:00
String sqlCommand = " CREATE TABLE " + tableName . toUpperCase ( ) + " ( " ;
2025-01-15 03:56:38 +00:00
for ( Pair < String , VALID_SQL_TYPE > colPair : columnPairs ) {
sqlCommand = sqlCommand + " " + colPair . GetKey ( ) + " " + SQLTypeSupport . GetSqlStrForType ( colPair . GetValue ( ) ) + " , " ;
2025-01-10 02:44:17 +00:00
}
2025-01-15 03:56:38 +00:00
// 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 ) { }
2025-01-10 02:44:17 +00:00
}
return success ;
}
2025-01-03 04:05:16 +00:00
}