]> WPIA git - gigi.git/blobdiff - src/org/cacert/gigi/database/DatabaseConnection.java
Merge branch 'felix-work'
[gigi.git] / src / org / cacert / gigi / database / DatabaseConnection.java
index 68ddd8c8bfcab692a358628a0dd53d0f33954f66..661565d843a0a3f1b428a8f114d6c92cfc34129f 100644 (file)
 package org.cacert.gigi.database;
 
-import java.io.FileInputStream;
-import java.io.IOException;
 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;
 
 public class DatabaseConnection {
-       Connection c;
-       HashMap<String, PreparedStatement> statements = new HashMap<String, PreparedStatement>();
-       static Properties credentials = new Properties();
-       static {
-               try {
-                       credentials.load(new FileInputStream("config/sql.properties"));
-               } catch (IOException e) {
-                       e.printStackTrace();
-               }
-       }
-       public DatabaseConnection() {
-               try {
-                       Class.forName(credentials.getProperty("driver"));
-               } catch (ClassNotFoundException e) {
-                       e.printStackTrace();
-               }
-               try {
-                       c = DriverManager.getConnection(credentials.getProperty("url"),
-                                       credentials.getProperty("user"),
-                                       credentials.getProperty("password"));
-               } catch (SQLException e) {
-                       e.printStackTrace();
-               }
-
-       }
-       public PreparedStatement prepare(String query) throws SQLException {
-               PreparedStatement statement = statements.get(query);
-               if (statement == null) {
-                       statement = c.prepareStatement(query);
-                       statements.put(query, statement);
-               }
-               return statement;
-       }
-
-       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<DatabaseConnection> instances = new ThreadLocal<DatabaseConnection>() {
-               @Override
-               protected DatabaseConnection initialValue() {
-                       return new DatabaseConnection();
-               }
-       };
-       public static DatabaseConnection getInstance() {
-               return instances.get();
-       }
+
+    public static final int CONNECTION_TIMEOUT = 24 * 60 * 60;
+
+    private Connection c;
+
+    private HashMap<String, GigiPreparedStatement> statements = new HashMap<String, GigiPreparedStatement>();
+
+    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';");
+            ps.setInt(1, CONNECTION_TIMEOUT);
+            ps.execute();
+            ps.close();
+            adHoc = c.createStatement();
+        } 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<DatabaseConnection> instances = new ThreadLocal<DatabaseConnection>() {
+
+        @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;
+    }
+
+    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();
+        }
+    }
 }