summaryrefslogtreecommitdiffstats
path: root/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/Database.java
diff options
context:
space:
mode:
authorSimon Rettberg2015-06-11 18:40:49 +0200
committerSimon Rettberg2015-06-11 18:40:49 +0200
commite0005ceecfd9281230c4add7575b18ee88307774 (patch)
treea73bbcfc213df478c701aac120ae2b7c6e52bb1b /dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/Database.java
parent[server] db stuff, new interface, ... (diff)
downloadtutor-module-e0005ceecfd9281230c4add7575b18ee88307774.tar.gz
tutor-module-e0005ceecfd9281230c4add7575b18ee88307774.tar.xz
tutor-module-e0005ceecfd9281230c4add7575b18ee88307774.zip
[server] On mah way (lots of restructuring, some early db classes, sql dump of current schema)
Diffstat (limited to 'dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/Database.java')
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/Database.java120
1 files changed, 120 insertions, 0 deletions
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/Database.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/Database.java
new file mode 100644
index 00000000..cfc6530b
--- /dev/null
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/Database.java
@@ -0,0 +1,120 @@
+package org.openslx.bwlp.sat.database;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Collections;
+import java.util.Queue;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import org.apache.log4j.Logger;
+import org.openslx.bwlp.sat.util.Configuration;
+
+public class Database {
+
+ private static final Logger LOGGER = Logger.getLogger(Database.class);
+ /**
+ * Pool of available connections.
+ */
+ private static final Queue<MysqlConnection> pool = new ConcurrentLinkedQueue<>();
+
+ /**
+ * Set of connections currently handed out.
+ */
+ private static final Set<MysqlConnection> busyConnections = Collections.newSetFromMap(new ConcurrentHashMap<MysqlConnection, Boolean>());
+
+ static {
+ try {
+ Class.forName("com.mysql.jdbc.Driver").newInstance();
+ } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
+ LOGGER.fatal("Cannot get mysql JDBC driver!", e);
+ System.exit(1);
+ }
+ }
+
+ /**
+ * Get a connection to the database. If there is a valid connection in the
+ * pool, it will be returned. Otherwise, a new connection is created. If
+ * there are more than 20 busy connections, <code>null</code> is returned.
+ *
+ * @return connection to database, or <code>null</code>
+ */
+ public static MysqlConnection getConnection() {
+ MysqlConnection con;
+ for (;;) {
+ con = pool.poll();
+ if (con == null)
+ break;
+ if (!con.isValid()) {
+ con.release();
+ continue;
+ }
+ if (!busyConnections.add(con))
+ throw new RuntimeException("Tried to hand out a busy connection!");
+ return con;
+ }
+ // No pooled connection
+ if (busyConnections.size() > 20) {
+ LOGGER.warn("Too many open MySQL connections. Possible connection leak!");
+ return null;
+ }
+ try {
+ // Create fresh connection
+ Connection rawConnection = DriverManager.getConnection(Configuration.getDbUri(),
+ Configuration.getDbUsername(), Configuration.getDbPassword());
+ // By convention in our program we don't want auto commit
+ rawConnection.setAutoCommit(false);
+ // Wrap into our proxy
+ con = new MysqlConnection(rawConnection);
+ // Keep track of busy mysql connection
+ if (!busyConnections.add(con))
+ throw new RuntimeException("Tried to hand out a busy connection!");
+ return con;
+ } catch (SQLException e) {
+ LOGGER.info("Failed to connect to local mysql server", e);
+ }
+ return null;
+ }
+
+ /**
+ * Called by a {@link MysqlConnection} when its <code>close()</code>-method
+ * is called, so the connection will be added to the pool of available
+ * connections again.
+ *
+ * @param connection
+ */
+ static void returnConnection(MysqlConnection connection) {
+ if (!busyConnections.remove(connection))
+ throw new RuntimeException("Tried to return a mysql connection to the pool that was not taken!");
+ pool.add(connection);
+ }
+
+ public static void printCharsetInformation() {
+ LOGGER.info("MySQL charset related variables:");
+ try (MysqlConnection connection = Database.getConnection()) {
+ MysqlStatement stmt = connection.prepareStatement("SHOW VARIABLES LIKE :what");
+ stmt.setString("what", "char%");
+ ResultSet rs = stmt.executeQuery();
+ while (rs.next()) {
+ LOGGER.info(rs.getString("Variable_name") + ": " + rs.getString("Value"));
+ }
+ stmt.setString("what", "collat%");
+ rs = stmt.executeQuery();
+ while (rs.next()) {
+ LOGGER.info(rs.getString("Variable_name") + ": " + rs.getString("Value"));
+ }
+ } catch (SQLException e) {
+ LOGGER.error("Query failed in Database.printCharsetInformation()", e);
+ }
+ LOGGER.info("End of variables");
+ }
+
+ public static void printDebug() {
+ LOGGER.info("Available: " + pool.size());
+ LOGGER.info("Busy: " + busyConnections.size());
+ }
+
+}// end class