package de.tud.kom.socom.database; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.SQLSyntaxErrorException; import java.sql.Statement; import de.tud.kom.socom.GlobalConfig; import de.tud.kom.socom.util.Logger; import de.tud.kom.socom.util.LoggerFactory; import de.tud.kom.socom.util.PlatformTools; import de.tud.kom.socom.util.ResourceLoader; /** * * @author Rhaban Hark * */ public class HSQLAccess implements GlobalConfig { private static final Logger logger = LoggerFactory.getLogger(); /* connection and reuseable statement object */ private Connection con; private static Statement query; private static HSQLAccess instance = new HSQLAccess(); /* Database specific strings */ // private static final String USERNAME = "socom"; // private static final String PASSWORD = "socom4kom"; // private static final String DATABASE_FILE = "database/socomdb"; /* LONGVARCHAR = BLOB, save TextHints like Binary GameContent */ // private static final String DATABASE_PROPERTIES = // "sql.longvar_is_lob=true"; private HSQLAccess() { try { startDatabase(); Class.forName("org.hsqldb.jdbc.JDBCDriver"); // con = DriverManager.getConnection("jdbc:hsqldb:file:" + // DATABASE_FILE + ";" + DATABASE_PROPERTIES, // USERNAME, PASSWORD); String db_host = ResourceLoader.getResource("db_host"); int db_port = Integer.parseInt(ResourceLoader.getResource("db_port")); String username = ResourceLoader.getResource("db_user"); String password = ResourceLoader.getResource("db_password"); con = DriverManager.getConnection("jdbc:hsqldb:hsql://" + db_host + ":" + db_port + "/socom", username, password); query = con.createStatement(); createTables(); } catch (SQLException e) { e.printStackTrace(); logger.Error(e); return; } catch (ClassNotFoundException e) { e.printStackTrace(); logger.Error(e); return; } logger.Info("***Database ready"); } private void startDatabase() { String[] dbexec = PlatformTools.isWindows() ? new String[]{"cmd.exe","/c","database-server.bat"} : new String[]{"./database-server.sh"}; logger.Info("Start Database Process"); try { Process databaseProcess = new ProcessBuilder(dbexec).directory(new File("database")).start(); BufferedReader reader = new BufferedReader(new InputStreamReader(databaseProcess.getInputStream())); String line = ""; String startupLine = "Startup sequence completed"; while((line = reader.readLine()) != null && !line.contains(startupLine)){ logger.Info(line); } reader.close(); Runtime.getRuntime().addShutdownHook(new Thread(){ public void run() { logger.Info("***Shutdown Database"); try { execQuery("SHUTDOWN"); } catch (Throwable e) { } } }); } catch (IOException e) { logger.Error(e); e.printStackTrace(); } } private void createTables() throws SQLException { try { for (String q : QueryStrings.allCreateQuerys) { query.execute(q); } for (String q : QueryStrings.allInsertQuerys) { query.execute(q); } } catch (SQLSyntaxErrorException e) { if (e.getMessage().contains("already exists")) logger.Info("Tables already exists - skip."); else throw e; } } public static HSQLAccess getInstance() { return instance; } /** * execute the sql queries without result, like INSERT * * @param query * @return either (1) the row count for SQL Data Manipulation Language (DML) * statements or (2) 0 for SQL statements that return nothing * @throws SQLException */ public synchronized int execQuery(String query) throws SQLException { return HSQLAccess.query.executeUpdate(query); } /** * execute the sql queries with result * * @param query * @return a ResultSet object that contains the data produced by the given * query; never null * @throws SQLException */ public synchronized ResultSet execQueryWithResult(String query) throws SQLException { return HSQLAccess.query.executeQuery(query); } public PreparedStatement getPreparedStatement(String query) throws SQLException { return con.prepareStatement(query); } public PreparedStatement getPreparedStatementGetKey(String query) throws SQLException { return con.prepareStatement(query, Statement.RETURN_GENERATED_KEYS); } }