X-Git-Url: https://code.wpia.club/?p=gigi.git;a=blobdiff_plain;f=src%2Forg%2Fcacert%2Fgigi%2Fdatabase%2FDatabaseConnection.java;h=5d987191a248452717c61e312f77d28fceaa6b95;hp=424723dd2ef7d4f9026ea9d0c7cffef2896163bd;hb=ff0add5c210e30565099394d8d6b4c3f5595c6c6;hpb=634b7f75c8fc2ed8799bad74731278fb59198c48 diff --git a/src/org/cacert/gigi/database/DatabaseConnection.java b/src/org/cacert/gigi/database/DatabaseConnection.java index 424723dd..5d987191 100644 --- a/src/org/cacert/gigi/database/DatabaseConnection.java +++ b/src/org/cacert/gigi/database/DatabaseConnection.java @@ -1,89 +1,168 @@ package org.cacert.gigi.database; +import java.io.IOException; +import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.Statement; import java.util.HashMap; import java.util.Properties; -import java.sql.Statement; + +import org.cacert.gigi.database.SQLFileManager.ImportType; public class DatabaseConnection { - public static final int CONNECTION_TIMEOUT = 24 * 60 * 60; - Connection c; - HashMap statements = new HashMap(); - private static Properties credentials = new Properties(); - Statement adHoc; - public DatabaseConnection() { - try { - Class.forName(credentials.getProperty("sql.driver")); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } - tryConnect(); - - } - private void tryConnect() { - try { - c = DriverManager.getConnection(credentials.getProperty("sql.url") - + "?zeroDateTimeBehavior=convertToNull", - credentials.getProperty("sql.user"), - credentials.getProperty("sql.password")); - PreparedStatement ps = c - .prepareStatement("SET SESSION wait_timeout=?;"); - ps.setInt(1, CONNECTION_TIMEOUT); - ps.execute(); - ps.close(); - adHoc = c.createStatement(); - } catch (SQLException e) { - e.printStackTrace(); - } - } - public PreparedStatement prepare(String query) throws SQLException { - ensureOpen(); - PreparedStatement statement = statements.get(query); - if (statement == null) { - statement = c.prepareStatement(query); - statements.put(query, statement); - } - return statement; - } - long lastAction = System.currentTimeMillis(); - private void ensureOpen() { - if (System.currentTimeMillis() - lastAction > CONNECTION_TIMEOUT * 1000L) { - try { - ResultSet rs = adHoc.executeQuery("SELECT 1"); - rs.close(); - lastAction = System.currentTimeMillis(); - return; - } catch (SQLException e) { - } - statements.clear(); - tryConnect(); - } - lastAction = System.currentTimeMillis(); - } - public static int lastInsertId(PreparedStatement query) throws SQLException { - ResultSet rs = query.getGeneratedKeys(); - rs.next(); - int id = rs.getInt(1); - rs.close(); - return id; - } - static ThreadLocal instances = new ThreadLocal() { - @Override - protected DatabaseConnection initialValue() { - return new DatabaseConnection(); - } - }; - public static DatabaseConnection getInstance() { - return instances.get(); - } - public static void init(Properties conf) { - if (credentials != null) { - throw new Error("Re-initiaizing is forbidden."); - } - credentials = conf; - } + + public static final int CURRENT_SCHEMA_VERSION = 1; + + public static final int CONNECTION_TIMEOUT = 24 * 60 * 60; + + private Connection c; + + private HashMap statements = new HashMap(); + + private static Properties credentials; + + private Statement adHoc; + + public DatabaseConnection() { + try { + Class.forName(credentials.getProperty("sql.driver")); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + tryConnect(); + + } + + private void tryConnect() { + try { + c = DriverManager.getConnection(credentials.getProperty("sql.url") + "?zeroDateTimeBehavior=convertToNull", credentials.getProperty("sql.user"), credentials.getProperty("sql.password")); + PreparedStatement ps = c.prepareStatement("SET SESSION wait_timeout=?, time_zone='+0:00';"); + try { + ps.setInt(1, CONNECTION_TIMEOUT); + ps.execute(); + adHoc = c.createStatement(); + } finally { + ps.close(); + } + } catch (SQLException e) { + e.printStackTrace(); + } + } + + public GigiPreparedStatement prepare(String query) { + ensureOpen(); + GigiPreparedStatement statement = statements.get(query); + if (statement == null) { + try { + statement = new GigiPreparedStatement(c.prepareStatement(query, Statement.RETURN_GENERATED_KEYS)); + } catch (SQLException e) { + throw new Error(e); + } + statements.put(query, statement); + } + return statement; + } + + private long lastAction = System.currentTimeMillis(); + + private void ensureOpen() { + if (System.currentTimeMillis() - lastAction > CONNECTION_TIMEOUT * 1000L) { + try { + ResultSet rs = adHoc.executeQuery("SELECT 1"); + rs.close(); + lastAction = System.currentTimeMillis(); + return; + } catch (SQLException e) { + } + statements.clear(); + tryConnect(); + } + lastAction = System.currentTimeMillis(); + } + + private static ThreadLocal instances = new ThreadLocal() { + + @Override + protected DatabaseConnection initialValue() { + return new DatabaseConnection(); + } + }; + + public static DatabaseConnection getInstance() { + return instances.get(); + } + + public static boolean isInited() { + return credentials != null; + } + + public static void init(Properties conf) { + if (credentials != null) { + throw new Error("Re-initiaizing is forbidden."); + } + credentials = conf; + GigiResultSet rs = getInstance().prepare("SELECT version FROM schemeVersion ORDER BY version DESC LIMIT 1").executeQuery(); + int version = 0; + if (rs.next()) { + version = rs.getInt(1); + } + if (version == CURRENT_SCHEMA_VERSION) { + return; // Good to go + } + if (version > CURRENT_SCHEMA_VERSION) { + throw new Error("Invalid database version. Please fix this."); + } + upgrade(version); + } + + private static void upgrade(int version) { + try { + Statement s = getInstance().c.createStatement(); + try { + while (version < CURRENT_SCHEMA_VERSION) { + try (InputStream resourceAsStream = DatabaseConnection.class.getResourceAsStream("upgrade/from_" + version + ".sql")) { + if (resourceAsStream == null) { + throw new Error("Upgrade script from version " + version + " was not found."); + } + SQLFileManager.addFile(s, resourceAsStream, ImportType.PRODUCTION); + } + version++; + } + s.addBatch("UPDATE schemeVersion SET version='" + version + "'"); + System.out.println("UPGRADING Database to version " + version); + s.executeBatch(); + System.out.println("done."); + } finally { + s.close(); + } + } catch (SQLException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void beginTransaction() throws SQLException { + c.setAutoCommit(false); + } + + public void commitTransaction() throws SQLException { + c.commit(); + c.setAutoCommit(true); + } + + public void quitTransaction() { + try { + if ( !c.getAutoCommit()) { + c.rollback(); + c.setAutoCommit(true); + } + } catch (SQLException e) { + e.printStackTrace(); + } + } }