[Schmitzm-commits] r1819 - in trunk/schmitzm-db: . .settings src/main/java src/main/java/de src/main/java/de/schmitzm src/main/java/de/schmitzm/postgres src/main/java/de/schmitzm/sql src/main/java/postgres src/main/java/sql

scm-commit@wald.intevation.org scm-commit at wald.intevation.org
Sat Jan 14 21:45:17 CET 2012


Author: alfonx
Date: 2012-01-14 21:45:15 +0100 (Sat, 14 Jan 2012)
New Revision: 1819

Added:
   trunk/schmitzm-db/src/main/java/de/
   trunk/schmitzm-db/src/main/java/de/schmitzm/
   trunk/schmitzm-db/src/main/java/de/schmitzm/postgres/
   trunk/schmitzm-db/src/main/java/de/schmitzm/postgres/PGUtil.java
   trunk/schmitzm-db/src/main/java/de/schmitzm/postgres/SqlQueryStat.java
   trunk/schmitzm-db/src/main/java/de/schmitzm/sql/
   trunk/schmitzm-db/src/main/java/de/schmitzm/sql/SqlUtil.java
Removed:
   trunk/schmitzm-db/src/main/java/postgres/PGUtil.java
   trunk/schmitzm-db/src/main/java/postgres/SqlQueryStat.java
   trunk/schmitzm-db/src/main/java/sql/SqlUtil.java
Modified:
   trunk/schmitzm-db/.classpath
   trunk/schmitzm-db/.settings/org.eclipse.core.resources.prefs
Log:
neues modul schmitzm-db

Modified: trunk/schmitzm-db/.classpath
===================================================================
--- trunk/schmitzm-db/.classpath	2012-01-14 20:38:46 UTC (rev 1818)
+++ trunk/schmitzm-db/.classpath	2012-01-14 20:45:15 UTC (rev 1819)
@@ -1,14 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
+	<classpathentry excluding="**/.svn" kind="src" output="target/classes" path="src/main/java"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
 	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"/>
-	<classpathentry kind="lib" path="/home/stefan/.m2/repository/postgresql/postgresql/9.1-901.jdbc4/postgresql-9.1-901.jdbc4.jar">
-		<attributes>
-			<attribute name="maven.groupId" value="postgresql"/>
-			<attribute name="maven.artifactId" value="postgresql"/>
-			<attribute name="maven.version" value="9.1-901.jdbc4"/>
-			<attribute name="maven.scope" value="compile"/>
-		</attributes>
-	</classpathentry>
 	<classpathentry kind="output" path="target/classes"/>
 </classpath>

Modified: trunk/schmitzm-db/.settings/org.eclipse.core.resources.prefs
===================================================================
--- trunk/schmitzm-db/.settings/org.eclipse.core.resources.prefs	2012-01-14 20:38:46 UTC (rev 1818)
+++ trunk/schmitzm-db/.settings/org.eclipse.core.resources.prefs	2012-01-14 20:45:15 UTC (rev 1819)
@@ -1,3 +1,4 @@
-#Sat Jan 14 21:27:48 CET 2012
+#Sat Jan 14 21:39:26 CET 2012
 eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
 encoding/<project>=UTF-8

Copied: trunk/schmitzm-db/src/main/java/de/schmitzm/postgres/PGUtil.java (from rev 1818, trunk/schmitzm-db/src/main/java/postgres/PGUtil.java)
===================================================================
--- trunk/schmitzm-db/src/main/java/postgres/PGUtil.java	2012-01-14 20:38:46 UTC (rev 1818)
+++ trunk/schmitzm-db/src/main/java/de/schmitzm/postgres/PGUtil.java	2012-01-14 20:45:15 UTC (rev 1819)
@@ -0,0 +1,971 @@
+package de.schmitzm.postgres;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.postgresql.util.PGInterval;
+
+import de.schmitzm.lang.LangUtil;
+
+/**
+ * Hilfsmethoden für PostgreSQL. Die Dependency soll nur {@link Connection} sein. In Hibernate kann über #doWork eine
+ * {@link Connection} erhalten werden.
+ */
+public class PGUtil {
+	static final Logger log = Logger.getLogger(PGUtil.class);
+
+	/**
+	 * PostgreSQL Privilegien die per Grant einer Tabelle zugeordnet werden können.<br/>
+	 * 
+	 * @see http://www.postgresql.org/docs/9.1/static/sql-grant.html
+	 */
+	public enum Privileges {
+		SELECT, INSERT, UPDATE, DELETE, REFERENCES, TEMPORARY, ALL_PRIVILEGES("ALL PRIVILEGES");
+
+		String sql;
+
+		Privileges() {
+			this.sql = super.toString();
+		}
+
+		Privileges(String sql) {
+			this.sql = sql;
+		}
+
+		@Override
+		public String toString() {
+			return this.sql;
+		}
+	}
+
+	/**
+	 * Fügt Privilegien für eine Rolle einer Tabelle hinzu.
+	 * 
+	 * @param tablename
+	 *            Tabellennamen, optional mit "schema.tablename"
+	 * @param targetRole
+	 *            Darf PUBLIC sein, oder Name einer ROLLE.
+	 * @param privileges
+	 *            List der zuzuordnenden Privilegien
+	 * @throws SQLException
+	 */
+	public static void grantPrivilegesOnTable(Connection c, String targetRole, String tablename,
+			Privileges... privileges) throws SQLException {
+		// GRANT SELECT, UPDATE, INSERT ON mytable TO admin;
+		String sql = "GRANT " + LangUtil.stringConcatWithSep(",", (Object[]) privileges) + " ON " + tablename + " TO "
+				+ targetRole;
+		c.createStatement().executeUpdate(sql);
+	}
+
+	/**
+	 * Entfernt Privilegien für eine Rolle von einre Tabelle.
+	 * 
+	 * @param tablename
+	 *            Tabellennamen, optional mit "schema.tablename"
+	 * @param privileges
+	 *            List der zuzuordnenden Privilegien
+	 * @throws SQLException
+	 */
+	public static void revokePrivilegesOnTable(Connection c, String tablename, String targetRole,
+			Privileges... privileges) throws SQLException {
+		// GRANT SELECT, UPDATE, INSERT ON mytable TO admin;
+		String sql = "REVOKE " + LangUtil.stringConcatWithSep(",", (Object[]) privileges) + " ON " + tablename
+				+ " FROM " + targetRole;
+		c.createStatement().executeUpdate(sql);
+	}
+
+	/**
+	 * Erstellt eine neue Rolle
+	 * 
+	 * @param rolename
+	 *            Name der neuen Rolle
+	 * @param inhRoles
+	 *            Rollen in denen die neue Rolle Mitglied ist
+	 */
+	public static void createRole(Connection c, String rolename, String... inhRoles) throws SQLException {
+		String sql = "CREATE ROLE " + rolename;
+		c.createStatement().executeUpdate(sql);
+		for (String inhRole : inhRoles)
+			c.createStatement().executeUpdate("GRANT " + inhRole + " TO " + rolename);
+	}
+
+	/**
+	 * Erstellt eine neue Rolle, wenn diese noch nicht existiert.
+	 * 
+	 * @param rolename
+	 *            Name der neuen Rolle
+	 * @param inhRoles
+	 *            Rollen in denen die neue Rolle Mitglied ist
+	 */
+	public static void createRoleIfNotExists(Connection c, String rolename, String... inhRoles) throws SQLException {
+		if (existsRole(c, rolename))
+			return;
+		createRole(c, rolename, inhRoles);
+	}
+
+	/**
+	 * Querys the <code>geometry_columns</code> table is part of every POSTGIS installation and must/should describe the
+	 * geometry columns and tables.
+	 */
+	static public String[] getColumnsDescribedInGeometryColumnsTable(Statement s) {
+		String[] columns = new String[0];
+		try {
+			ResultSet rs = s.executeQuery("SELECT f_table_name FROM geometry_columns;");
+			try {
+
+				while (rs.next()) {
+					columns = LangUtil.extendArray(columns, rs.getString(1));
+				}
+			} finally {
+				rs.close();
+			}
+		} catch (SQLException e) {
+			log.error(e, e);
+		}
+
+		return columns;
+
+	}
+
+	/**
+	 * Creates or Updates
+	 * 
+	 * @param tableName
+	 * @param geoColumnName
+	 * @param srid
+	 */
+	@Deprecated
+	// tut noch nicht
+	public static void createOrUpdateGeometrysColumnsEntry(String tableName, String geoColumnName, int srid) {
+
+		String createGeometryEntrySQL = "INSERT INTO geometry_columns (f_table_catalog, f_table_schema, f_table_name, f_geometry_column, coord_dimension, srid, \"type\") VALUES ( '', 'public', '"
+				+ tableName + "', '" + geoColumnName + "', 2, " + srid + ",'MULTIPOLYGON' ) LIMIT 1;";
+	}
+
+	// TODO isGeoColumn();
+
+	/**
+	 * @param binding
+	 *            Eine "einfache" Javaklasse, die in PG abgebildet werden soll.
+	 * @return einen PG-spezifischen Datentypenamen für einen Javatyp zurück, z.b. "double precision" für
+	 *         <code>Double.class</code>
+	 */
+	public static String getColTypeName(Class<?> binding) {
+
+		if (binding.isAssignableFrom(Double.class)) {
+			return "double precision"; // eg 'number' at oracle
+		} else if (binding.isAssignableFrom(String.class)) {
+			return "text";
+		} else if (binding.isAssignableFrom(Integer.class)) {
+			return "integer";
+		} else if (binding.isAssignableFrom(Long.class)) {
+			return "bigint";
+		}
+
+		throw new RuntimeException("DB Type mapping for " + binding + " not yet implemented.");
+	}
+
+	/**
+	 * Legt ein Schema an, wenn es vorher nicht existierte.
+	 * 
+	 * @return <code>true</code> wenn das Schema neu angelegt wurde.
+	 */
+	public static boolean createSchemaIfNotExists(Connection c, String schemaname) throws SQLException {
+		if (!existsSchema(c, schemaname)) {
+			c.createStatement().execute("create schema " + schemaname.toLowerCase());
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Liefert <code>true</code> wenn ein Schema mit dem Namen in der PG Datenbank existiert.
+	 */
+	public static boolean existsSchema(Connection c, String schemaname) throws SQLException {
+		String sql = "select 1 from pg_catalog.pg_namespace where nspname = '" + schemaname.toLowerCase() + "'";
+		ResultSet rs = c.createStatement().executeQuery(sql);
+		try {
+			return rs.next();
+		} finally {
+			rs.close();
+		}
+
+	}
+
+	/**
+	 * Liefert eine Liste der Rollen in denen der Übergebenen USER (Login role) ist. <br/>
+	 * Tested with PG 8.4
+	 */
+	public static List<String> listRolesForUser(Connection c, String username) throws SQLException {
+		List<String> roles = new ArrayList<String>();
+		String sql = "select rolname from pg_user join pg_auth_members on (pg_user.usesysid=pg_auth_members.member) join pg_roles on (pg_roles.oid=pg_auth_members.roleid) where pg_user.usename='"
+				+ username.toLowerCase() + "'";
+		ResultSet rs = c.createStatement().executeQuery(sql);
+		try {
+			while (rs.next()) {
+				roles.add(rs.getString(1));
+			}
+		} finally {
+			rs.close();
+		}
+		return roles;
+	}
+
+	/**
+	 * Liefert alle Benutzer der DB zurück.
+	 * 
+	 * @throws SQLException
+	 */
+	public static List<String> listUsers(Connection c) throws SQLException {
+		List<String> roles = new ArrayList<String>();
+		ResultSet rs = c.createStatement().executeQuery("select * from pg_user");
+		try {
+			while (rs.next()) {
+				roles.add(rs.getString(1));
+			}
+		} finally {
+			rs.close();
+		}
+		return roles;
+	}
+
+	/**
+	 * Liste aller Tabellennamen in diesem Schema, ohne die Schemaangabe im Namen. (Also 'anreden' und nicht
+	 * 'public.anreden') <br/>
+	 * Tested with PG 8.4
+	 * 
+	 * @param schemaname
+	 *            if <code>null</code>, <code>public</code> is used.
+	 */
+	public static List<String> listTablesInSchema(Connection c, String schemaname) throws SQLException {
+		List<String> tables = new ArrayList<String>();
+
+		String sql = "select tablename from pg_tables where schemaname = '" + schemaname.toLowerCase() + "'";
+		ResultSet rs = c.createStatement().executeQuery(sql);
+		try {
+			while (rs.next()) {
+				tables.add(rs.getString(1));
+			}
+		} finally {
+			rs.close();
+		}
+		return tables;
+	}
+
+	/**
+	 * Liefert <code>true</code> wenn der Benutzername im DBMS Superuser ist.
+	 */
+	public static boolean isSuperuser(Connection c, String username) throws SQLException {
+		ResultSet rs = c.createStatement().executeQuery(
+				"select usesuper from pg_user where usename = '" + username + "' and usesuper = true");
+		try {
+			if (rs.next()) {
+				return true;
+			}
+		} finally {
+			rs.close();
+		}
+		return false;
+	}
+
+	public static boolean existsRole(Connection c, String rolename) throws SQLException {
+		String sql = "select count(1) from pg_roles where rolname = '" + rolename.toLowerCase() + "'";
+		ResultSet rs = c.createStatement().executeQuery(sql);
+		try {
+			if (rs.next())
+				return rs.getInt(1) > 0;
+		} finally {
+			rs.close();
+		}
+		return false;
+	}
+
+	public static void removeAllPrivilegesFrom(Connection c, String rolename, String tablename) throws SQLException {
+		c.createStatement().executeUpdate(
+				"revoke all on TABLE " + tablename.toLowerCase() + " from " + rolename.toLowerCase() + " cascade");
+	}
+
+	/**
+	 * Löscht eine Rolle wenn sie vorher existiert
+	 */
+	public static void dropRoleIfExists(Connection c, String rolename) throws SQLException {
+		c.createStatement().executeUpdate("drop role if exists " + rolename.toLowerCase());
+	}
+
+	/**
+	 * Löscht einen Trigger wenn er vorher existierte.
+	 * 
+	 * @param c
+	 * @param triggerName
+	 * @param tableName
+	 */
+	public static void dropTriggerIfExists(Connection c, String triggerName, String tableName) throws SQLException {
+		c.createStatement().executeUpdate("drop TRIGGER if exists " + triggerName.toLowerCase() + " ON " + tableName);
+	}
+
+	/**
+	 * 
+	 * @param c
+	 * @param name
+	 *            z.B.: keckformel wird dann zu keckformel()
+	 * @param plCommands
+	 *            z.B.
+	 *            <code>NEW.kpk_kreis = NEW.risiko_soz+NEW.risiko_emo+NEW.risiko_moti +NEW.risiko_spr+NEW.risiko_wohl;</code>
+	 *            OHNE <code>RETURN NEW</code>, das wird automatisch angehangen.
+	 * @throws SQLException
+	 */
+	public static void createOrReplaceTriggerFunction(Connection c, String name, String plCommands) throws SQLException {
+		// System.err.println(plCommands);
+
+		// String sql = "CREATE OR REPLACE FUNCTION " + name + "()" + " RETURNS trigger AS $" + name
+		// + "$\nBEGIN\n?\nRETURN NEW;" + "\nEND;\n$" + name + "$ LANGUAGE 'plpgsql'";
+		// PreparedStatement ps = c.prepareStatement(sql);
+		// ps.setString(0, plCommands);
+		// ps.executeUpdate();
+
+		// String sql = "CREATE OR REPLACE FUNCTION " + name + "()" + " RETURNS trigger AS $" + name + "$\nBEGIN\n "
+		// + plCommands + " \nRETURN NEW;" + "\nEND;\n$" + name + "$ LANGUAGE 'plpgsql'";
+		// c.createStatement().executeUpdate(sql);
+
+		createOrReplaceFunction(c, name, null, "TRIGGER", null, plCommands + "\nRETURN NEW");
+	}
+
+	/**
+	 * 
+	 * @param c
+	 * @param name
+	 *            z.B.: keckformel wird dann zu keckformel()
+	 * @param parameters
+	 *            Parameter der Funcktion, kann <code>null</code> sein.
+	 * @param returns
+	 *            z.B. <code>TRIGGER</code> oder <code>SETOF bigint</code> oder "void"
+	 * @param declare
+	 *            Declare block oder <code>null</code>
+	 * @param plCommands
+	 *            z.B. NEW.kpk_kreis = NEW.risiko_soz+NEW.risiko_emo+NEW.risiko_moti +NEW.risiko_spr+NEW.risiko_wohl;
+	 */
+	public static void createOrReplaceFunction(Connection c, String name, String parameters, String returns,
+			String declare, String plCommands) throws SQLException {
+		// System.err.println(plCommands);
+
+		// String sql = "CREATE OR REPLACE FUNCTION " + name + "()" + " RETURNS trigger AS $" + name
+		// + "$\nBEGIN\n?\nRETURN NEW;" + "\nEND;\n$" + name + "$ LANGUAGE 'plpgsql'";
+		// PreparedStatement ps = c.prepareStatement(sql);
+		// ps.setString(0, plCommands);
+		// ps.executeUpdate();
+
+		parameters = LangUtil.removeWhitespacesToEmpty(parameters);
+		declare = LangUtil.removeWhitespacesToEmpty(declare);
+
+		String sql = "CREATE OR REPLACE FUNCTION " + name + "(" + parameters + ")" + " RETURNS " + returns + " AS $$\n"
+				+ "DECLARE\n" + declare + "\n" + "BEGIN\n " + plCommands + ";" + "\nEND;\n$$ LANGUAGE 'plpgsql'";
+		c.createStatement().executeUpdate(sql);
+	}
+
+	/**
+	 * Erstellt einen <code>FOR EACH ROW EXECUTE PROCEDURE</code> trigger für eine Tabelle
+	 * 
+	 * @param c
+	 * @param triggerName
+	 * @param type
+	 *            z.B. "BEFORE INSERT OR UPDATE"
+	 * @param tableName
+	 * @param plCommands
+	 *            PSQL commands, e.g.<br/>
+	 *            <code>
+	    IF ((TG_OP = 'UPDATE') or (TG_OP = 'INSERT') ) THEN
+            INSERT INTO workqueue values (NEW.id);
+            RETURN NEW;
+        END IF;
+        </code>
+	 */
+	public static void createOrRecreateTrigger(Connection c, String triggerName, String type, String tableName,
+			String plCommands) throws SQLException {
+		dropTriggerIfExists(c, triggerName, tableName);
+		createOrReplaceTriggerFunction(c, triggerName + "_fn", plCommands);
+		c.createStatement().executeUpdate(
+				"CREATE TRIGGER " + triggerName + " " + type + " ON " + tableName + " FOR EACH ROW EXECUTE PROCEDURE "
+						+ triggerName + "_fn" + "()");
+	}
+
+	/**
+	 * @param tableName
+	 *            e.g. 'inseratabfragen_kvps'
+	 * @param columns
+	 *            e.g. 'inseratabfrage_id'
+	 * @param idxNamePostfix
+	 *            e.g. 'idx1'
+	 * @param unique
+	 *            <code>true</code> if the columns are unique. A UNIQUE INDEX will be created.
+	 */
+	public static void addIndex(Connection c, final String tableName, final String columns, String idxPostfix,
+			final boolean unique) throws SQLException {
+		addIndex(c, tableName, columns, idxPostfix, unique, null, null, false, null);
+	}
+
+	/**
+	 * Liefert eine Liste aller Indexnamen die für eine Tabelle existieren. Der Tabellenname wird mit <code>like</code>
+	 * verglichen, darf also <code>%</code> enthalten.<br/>
+	 * Achtung: Diese abfrage ist nicht Schema-Spezifisch. Eine schema. Angabe vor dem tabellennamen wird automatisch
+	 * entfernt.
+	 */
+	public static List<String> listIndexesForTable(Connection c, String tableName) throws SQLException {
+		Statement s = c.createStatement();
+
+		if (tableName.contains("."))
+			tableName = tableName.substring(tableName.indexOf(".") + 1, tableName.length());
+
+		List<String> idxes = new ArrayList<String>();
+
+		// , array_to_string(array_agg(a.attname), ', ') as column_names
+		String sql = "select t.relname as table_name, i.relname as index_name from pg_class t, pg_class i, pg_index ix, pg_attribute a where t.oid = ix.indrelid and i.oid = ix.indexrelid and a.attrelid = t.oid and a.attnum = ANY(ix.indkey) and t.relkind = 'r' and t.relname like '"
+				+ tableName + "' group by t.relname, i.relname order by t.relname, i.relname";
+
+		ResultSet rs = s.executeQuery(sql);
+		try {
+			while (rs.next()) {
+				idxes.add(rs.getString(2));
+			}
+		} finally {
+			rs.close();
+		}
+
+		return idxes;
+
+	}
+
+	/**
+	 * @param tableName
+	 *            e.g. 'inseratabfragen_kvps'
+	 * @param columns
+	 *            e.g. 'inseratabfrage_id'
+	 * @param idxNamePostfix
+	 *            e.g. 'idx1'
+	 * @param unique
+	 *            <code>true</code> if the columns are unique. A UNIQUE INDEX will be created.
+	 * @param tablespace
+	 *            <code>null</code> oder der name des tablespace in dem der Index liegen soll.
+	 * @param type
+	 *            <code>null</code> für DB default oder "hash" oder "btree" oder "gin" etc...
+	 * @param forceRecreationIfExistsAlready
+	 *            wenn <code>true</code> dann werden der Index vorher gedroppt falls er exisitert.
+	 * @param fillFactor
+	 *            Wert von >0. -> 1. Bei .5 wird für den Index doppelt so viel Platz reserviert wie aktuell benötig, um
+	 *            auf weiteres Wachstum der Tabelle ohne Indexfragmentierung reagieren zu können.
+	 */
+	public static void addIndex(Connection c, final String tableName, final String columns, String idxPostfix,
+			final boolean unique, String tablespace, String type, boolean forceRecreationIfExistsAlready,
+			Double fillFactor) throws SQLException {
+		String idxNameWithDot = tableName + "_" + idxPostfix;
+		final String idxName = idxNameWithDot.replace(".", "_");
+
+		// Wenn der Tablename ein Schema mit "schema.name" enthält, dann liefert
+		// listIndexesForTable hier ein schema_table im Index-Namen zurück. Der
+		// "." wird also zu einem "_"
+		for (String existIdxName : listIndexesForTable(c, tableName)) {
+			if (existIdxName.equalsIgnoreCase(idxName.replaceFirst("\\.", "_"))) {
+				// Existiert bereits.
+
+				if (!forceRecreationIfExistsAlready)
+					return;
+
+				log.info("Aufgrund von forceRecreationIfExistsAlready=true wird der Index " + idxNameWithDot
+						+ " jetzt gedroppt.");
+
+				Statement s = c.createStatement();
+
+				// Hier die Schreibweise mit . für schematrennung verwenden
+				final String queryString = "DROP INDEX " + idxNameWithDot;
+				try {
+					s.execute(queryString);
+					c.commit();
+					log.debug("Index dropped: " + queryString);
+				} catch (SQLException e) {
+					c.rollback();
+					Throwable cause = e;
+					if (e.getCause() != null)
+						cause = e.getCause();
+
+					// keine Ausgabe bei: already EXISTs, EXISTiert
+					// bereits,
+					// ...
+					// Ex abfangen, wenn IDX schon existiert
+
+					String msg = cause.getMessage();
+					log.error(e.getLocalizedMessage(), e);
+					return;
+				}
+
+				break;
+
+			}
+		}
+
+		Statement s = c.createStatement();
+
+		if (fillFactor != null && (fillFactor <= 0. || fillFactor > 1.))
+			throw new IllegalArgumentException("fillFactor muss großer 0 und kleinergleich 1 sein.");
+
+		String sqlFillFactor = "";
+		if (fillFactor != null)
+			sqlFillFactor = " WITH (FILLFACTOR=" + (int) (fillFactor * 100) + ") ";
+
+		String sqlTableSpace = (tablespace == null || tablespace.equalsIgnoreCase("null") || !existsTablespace(c,
+				tableName)) ? "" : " TABLESPACE " + tablespace;
+
+		String sqlUsing = type == null ? "" : " USING " + type;
+
+		final String queryString = "CREATE " + (unique ? "UNIQUE " : "") + "INDEX " + idxName + " ON " + tableName
+				+ sqlUsing + " (" + columns + ") " + sqlFillFactor + sqlTableSpace;
+		try {
+			s.execute(queryString);
+			c.commit();
+			log.info("Neuen Index erstellt: " + queryString);
+		} catch (SQLException e) {
+			c.rollback();
+			Throwable cause = e;
+			if (e.getCause() != null)
+				cause = e.getCause();
+
+			// keine Ausgabe bei: already EXISTs, EXISTiert
+			// bereits,
+			// ...
+			// Ex abfangen, wenn IDX schon existiert
+
+			String msg = cause.getMessage();
+			if (msg.endsWith("already exists") || msg.endsWith("existiert bereits")) {
+				// TO NOTHING, IDX already exists
+				log.info("Index existierte bereits, nicht neuerstellt: " + queryString);
+			} else
+				log.error(e.getLocalizedMessage(), e);
+
+		}
+
+	}
+
+	/**
+	 * Liefert <code>true</code> wenn ein tablespace mit dem Namen existiert.
+	 * 
+	 * @throws SQLException
+	 */
+	private static boolean existsTablespace(Connection c, String spaceName) throws SQLException {
+
+		// SELECT count(1) FROM pg_tablespace where spcname = 'spcname';
+		String stmtSql = "SELECT COUNT(*) FROM pg_tablespace where spcname = '" + spaceName + "'";
+
+		PreparedStatement stmt = c.prepareStatement(stmtSql);
+		stmt.execute();
+
+		ResultSet result = stmt.getResultSet();
+		try {
+			int count = 0;
+			if (result.next())
+				count = result.getInt(1);
+
+			return count > 0;
+		} finally {
+			result.close();
+			stmt.close();
+		}
+
+	}
+
+	/**
+	 * Fügt einen Benutzer zu einer Rolle hinzu. Wenn der benutzer bereits in der Rolle enthalten ist, wird keine
+	 * Exception geschmisssen.
+	 * 
+	 * @throws SQLException
+	 */
+	public static void grantRoleToUser(Connection c, String rolename, String username) throws SQLException {
+		c.createStatement().executeUpdate("GRANT " + rolename + " TO " + username);
+	}
+
+	/**
+	 * Der : (Doppelpunkt) hat in PSQL eine besondere Bedeutung. Er wind mit dieser methode escaped. Diese Methode
+	 * sollte mit <code>like E'"+PGUtil.escape(...)+"'</code> verwendet werden.
+	 */
+	public static String escape(String key) {
+		key = key.replaceAll(":", "\\:");
+		return key;
+	}
+
+	/**
+	 * Liefert die Anzahl der offenen Sessions zur Datenbank.
+	 * 
+	 * @param c
+	 *            DB-Verbindung
+	 * @param dbName
+	 *            Name der Datenbank fuer die die Sessions gezaehlt werden (kann {@code null} sein)
+	 * @param userName
+	 *            Name des Users fuer den die Sessions gezaehlt werden (kann {@code null} sein)
+	 */
+	public static int getOpenSessionCount(Connection c, String dbName, String userName) throws SQLException {
+		return getOpenSessionCount(c, dbName, userName, null);
+	}
+
+	/**
+	 * Liefert die Anzahl der offenen Sessions zur Datenbank.
+	 * 
+	 * @param c
+	 *            DB-Verbindung
+	 * @param dbName
+	 *            Name der Datenbank fuer die die Sessions gezaehlt werden (kann {@code null} sein)
+	 * @param userName
+	 *            Name des Users fuer den die Sessions gezaehlt werden (kann {@code null} sein)
+	 * @param queryLike
+	 *            like-Beindung auf die Query die in der Session ausgeführt wird, oder <code>null</code>
+	 */
+	public static int getOpenSessionCount(Connection c, String dbName, String userName, String queryLike)
+			throws SQLException {
+		String stmtSql = "SELECT COUNT(*) FROM pg_stat_activity WHERE TRUE";
+
+		if (dbName != null)
+			stmtSql += " AND datname = ?";
+		if (userName != null)
+			stmtSql += " AND usename = ?";
+		if (queryLike != null) {
+			stmtSql += " AND current_query like '" + queryLike + "'";
+		}
+
+		PreparedStatement stmt = c.prepareStatement(stmtSql);
+		if (dbName != null)
+			stmt.setString(1, dbName);
+		if (userName != null)
+			stmt.setString(2, userName);
+		stmt.execute();
+
+		ResultSet result = stmt.getResultSet();
+		try {
+			int count = 0;
+			if (result.next())
+				count = result.getInt(1);
+
+			return count;
+		} finally {
+			result.close();
+			stmt.close();
+		}
+	}
+
+	/**
+	 * Liefert <code>true</code> wenn eine Spalte mit dem Namen in der angegebenen Tabelle existiert. Die Tablle darf
+	 * optional mit "schema." prefixiert werden.
+	 */
+	public static boolean existsColumn(Connection c, String tableName, String columnName) throws SQLException {
+
+		String schema = "public";
+
+		if (tableName.contains(".")) {
+			final String[] split = tableName.split("\\.");
+			schema = split[0];
+			tableName = split[1];
+		}
+
+		ResultSet nativeCheckExistsColumnQuery = c.createStatement().executeQuery(
+				"SELECT * FROM information_schema.COLUMNS WHERE COLUMN_NAME = '" + columnName.toLowerCase()
+						+ "' AND TABLE_NAME='" + tableName + "' AND TABLE_SCHEMA='" + schema + "';");
+		return nativeCheckExistsColumnQuery.next();
+	}
+
+	/**
+	 * Existiert ein relationsname als View?
+	 * 
+	 * @param viewName
+	 *            Darf eine Schemaangabe mit . Trenner enthalten.
+	 * @throws SQLException
+	 */
+	public static boolean existsView(Connection c, String viewName) throws SQLException {
+
+		String schema = "public";
+
+		if (viewName.contains(".")) {
+			final String[] split = viewName.split("\\.");
+			schema = split[0];
+			viewName = split[1];
+		}
+
+		final String checkView = "SELECT * FROM information_schema.VIEWS where table_schema = '" + schema
+				+ "' and table_name = '" + viewName + "' LIMIT 1";
+		ResultSet rs = c.createStatement().executeQuery(checkView);
+
+		try {
+			return rs.next();
+		} finally {
+			rs.close();
+		}
+	}
+
+	public static void dropViewIfExists(Connection c, String viewName) throws SQLException {
+		final String dropView = "DROP VIEW IF EXISTS " + viewName;
+		c.createStatement().executeUpdate(dropView);
+	}
+
+	/**
+	 * Liefert eine Liste der aktuell laufenden Queries und ihrere Laufzeiten zurück. Der 2. Teil der Rückgabepaare ist
+	 * ein String der einem PG Interval entspricht. Dieses kann mit der Klasse PGInterval geparst werden.<br/>
+	 * 
+	 * @param datName
+	 *            <code>null</code> oder der Datenbankname, auf den die Abfrage gefiltert werden soll.
+	 * 
+	 * @param minSecondsRunning
+	 *            <code>null</code> oder die zurückgegebenen Anfragen müssen mindestens soviele Sekunden schon laufen.
+	 */
+	static public List<SqlQueryStat> listQueries(Connection c, String datName, Integer minSecondsRunning)
+			throws SQLException {
+		ArrayList<SqlQueryStat> result = new ArrayList<SqlQueryStat>();
+
+		String where = "where current_query not like '%IDLE%' ";
+
+		if (datName != null)
+			where += " and datname like '" + datName + "'";
+
+		if (minSecondsRunning != null) {
+			if (minSecondsRunning < 0)
+				throw new IllegalStateException();
+
+			where += " and age (now(),query_start) >= interval '" + minSecondsRunning + " second' ";
+		}
+
+		final String sql = "select current_query, age (now(),query_start) as qage, waiting, procpid from pg_stat_activity "
+				+ where + " order by qage desc";
+		ResultSet rs = c.createStatement().executeQuery(sql);
+
+		try {
+			while (rs.next()) {
+				String q = rs.getString(1);
+				String age = rs.getString(2);
+				boolean waiting = rs.getBoolean(3);
+				Long procId = rs.getLong(4);
+
+				result.add(new SqlQueryStat(q, new PGInterval(age), waiting, procId));
+			}
+
+		} finally {
+			rs.close();
+		}
+		return result;
+	}
+
+	/**
+	 * Tablename der optinal als das Schema enthalten darf.
+	 */
+	public static boolean removeColumn(Connection c, String tableName, String columnName) throws SQLException {
+
+		// Das eigentliche erstellen der neuen Spalte
+		String queryString = "ALTER TABLE " + tableName + " DROP COLUMN " + columnName;
+
+		// System.out.println(queryString);
+
+		int result = c.createStatement().executeUpdate(queryString);
+
+		if (result != 0) {
+			// JRegDBUtils.log.error(queryString + " returned not 0 = " +
+			// result);
+			return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Liefert die COLUMN-NAMES eines PKs einer Tabelle
+	 * 
+	 * @param dbc
+	 *            Connection to Postgressql Database
+	 * @param tableName
+	 *            darf Schemanamen enthalten.
+	 * 
+	 * @return Primary Key. <code>NULL</code> if empty
+	 */
+	public static String getPrimaryKey(Connection dbc, String tableName) throws SQLException {
+
+		String schema = "public";
+		if (tableName.contains(".")) {
+			final String[] split = tableName.split("\\.");
+			schema = split[0];
+			tableName = split[1];
+		}
+
+		Statement s = dbc.createStatement();
+		ResultSet rs = s
+				.executeQuery("select distinct(column_name) from INFORMATION_SCHEMA.KEY_COLUMN_USAGE a,INFORMATION_SCHEMA.TABLE_CONSTRAINTS b where constraint_type = 'PRIMARY KEY' and a.table_name='"
+						+ tableName + "' and a.table_schema='" + schema + "';");
+
+		String pk = "";
+		try {
+
+			while (rs.next()) {
+				pk += rs.getString("column_name");
+			}
+
+		} finally {
+			rs.close();
+		}
+
+		if (pk.endsWith(","))
+			pk = pk.substring(0, pk.length() - 1);
+
+		return pk.isEmpty() ? null : pk;
+
+	}
+
+	/**
+	 * Returns cardinality of column in table
+	 */
+	public long getCardinality(Connection dbc, String tableName, String column) throws SQLException {
+		String sql = "select count( DISTINCT " + "(" + column + ")" + ") " + "from " + tableName;
+		ResultSet countRs = dbc.createStatement().executeQuery(sql);
+		try {
+			countRs.next();
+			return ((Number) countRs.getLong(1)).longValue();
+		} finally {
+			countRs.close();
+		}
+	}
+
+	public static boolean isIntColumn(Connection c, String tableName, String columnName) throws SQLException {
+		String schema = "public";
+		if (tableName.contains(".")) {
+			final String[] split = tableName.split("\\.");
+			schema = split[0];
+			tableName = split[1];
+		}
+
+		Statement s = c.createStatement();
+		ResultSet rs = s.executeQuery("SELECT data_type FROM information_schema.COLUMNS WHERE COLUMN_NAME = '"
+				+ columnName.toLowerCase() + "' AND TABLE_NAME='" + tableName + "' AND TABLE_SCHEMA='" + schema + "';");
+		try {
+
+			rs.next();
+			String typeDef = rs.getString(1);
+			Boolean isNumeric = false;
+			isNumeric |= typeDef.startsWith("numeric");
+
+			return isNumeric;
+		} finally {
+			rs.close();
+		}
+	}
+
+	/**
+	 * Typischer Weise POSTGIS, wenn man sonst nichts anderen installiert hat.
+	 */
+	public static boolean isUserDefinedColumn(Connection c, String tableName, String columnName) throws SQLException {
+
+		String schema = "public";
+		if (tableName.contains(".")) {
+			final String[] split = tableName.split("\\.");
+			schema = split[0];
+			tableName = split[1];
+		}
+
+		Statement s = c.createStatement();
+		ResultSet rs = s.executeQuery("SELECT data_type FROM information_schema.COLUMNS WHERE COLUMN_NAME = '"
+				+ columnName.toLowerCase() + "' AND TABLE_NAME='" + tableName + "' AND TABLE_SCHEMA='" + schema + "';");
+		rs.next();
+		String typeDef = rs.getString(1);
+		return typeDef.toUpperCase().startsWith("USER-DEFINED");
+	}
+
+	public static boolean isTextColumn(Connection c, String tableName, String columnName) throws SQLException {
+
+		String schema = "public";
+		if (tableName.contains(".")) {
+			final String[] split = tableName.split("\\.");
+			schema = split[0];
+			tableName = split[1];
+		}
+
+		Statement s = c.createStatement();
+		ResultSet rs = s.executeQuery("SELECT data_type FROM information_schema.COLUMNS WHERE COLUMN_NAME = '"
+				+ columnName.toLowerCase() + "' AND TABLE_NAME='" + tableName + "' AND TABLE_SCHEMA='" + schema + "';");
+		try {
+			rs.next();
+			String typeDef = rs.getString(1);
+			Boolean isText = false;
+			isText |= typeDef.startsWith("text");
+			isText |= typeDef.startsWith("character");
+
+			return isText;
+		} finally {
+			rs.close();
+		}
+	}
+
+	/**
+	 * Creates a new Column.
+	 * 
+	 * @param dbc
+	 * @param tableName
+	 * @param columnName
+	 * @param colTypeName
+	 * @param comment
+	 * @return
+	 * @throws SQLException
+	 */
+	public static boolean addColumn(Connection dbc, String tableName, String columnName, String colTypeName,
+			String comment) throws SQLException {
+
+		if (dbc == null)
+			throw new IllegalStateException("Es besteht keine Datenbankverbindung!");
+
+		Statement s = dbc.createStatement();
+
+		if (existsColumn(dbc, tableName, columnName)) {
+			return false;
+		}
+
+		// Das eigentliche erstellen der neuen Spalte
+		String queryString = "ALTER TABLE " + tableName + " ADD " + columnName + " " + colTypeName;
+
+		// JRegDBUtils.log.debug(queryString);
+
+		int result = s.executeUpdate(queryString);
+
+		if (result != 0) {
+			return false;
+		}
+
+		if (comment != null && !comment.isEmpty()) {
+			queryString = "COMMENT ON COLUMN " + tableName + "." + columnName + " IS '" + comment + "';";
+		}
+
+		s.close();
+
+		return true;
+	}
+
+	/**
+	 * Liefert alle Spalten einer Tabelle
+	 */
+	public static ArrayList<String> getAllColumnsOf(Connection dbc, String tableName) throws SQLException {
+		String schema = "public";
+		if (tableName.contains(".")) {
+			final String[] split = tableName.split("\\.");
+			schema = split[0];
+			tableName = split[1];
+		}
+
+		ArrayList<String> cols = new ArrayList<String>();
+
+		// String tableName = PropertyUtils.getDbTableName(i);
+
+		String sql = "SELECT column_name FROM information_schema.COLUMNS WHERE TABLE_NAME = '" + tableName
+				+ "' and TABLE_SCHEMA = '" + schema + "';";
+
+		ResultSet colsRs = dbc.createStatement().executeQuery(sql);
+		try {
+			while (colsRs.next())
+				cols.add(colsRs.getString(1));
+		} finally {
+			colsRs.close();
+		}
+		return cols;
+	}
+
+}


Property changes on: trunk/schmitzm-db/src/main/java/de/schmitzm/postgres/PGUtil.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Copied: trunk/schmitzm-db/src/main/java/de/schmitzm/postgres/SqlQueryStat.java (from rev 1818, trunk/schmitzm-db/src/main/java/postgres/SqlQueryStat.java)
===================================================================
--- trunk/schmitzm-db/src/main/java/postgres/SqlQueryStat.java	2012-01-14 20:38:46 UTC (rev 1818)
+++ trunk/schmitzm-db/src/main/java/de/schmitzm/postgres/SqlQueryStat.java	2012-01-14 20:45:15 UTC (rev 1819)
@@ -0,0 +1,63 @@
+package de.schmitzm.postgres;
+
+import java.sql.SQLException;
+
+import org.apache.log4j.Logger;
+import org.postgresql.util.PGInterval;
+
+/**
+ * Beschreibt eine laufende SQL Aktion.
+ * 
+ * TODO schmitzm-pg
+ */
+public class SqlQueryStat {
+
+	final static Logger log = Logger.getLogger(SqlQueryStat.class);
+	private final boolean waiting;
+
+	public SqlQueryStat(String query, String interval, boolean waiting, Long procId) {
+		this.query = query;
+		this.waiting = waiting;
+		this.procId = procId;
+		PGInterval runningFor_;
+		try {
+			runningFor_ = new PGInterval(interval);
+		} catch (SQLException e) {
+			log.error(e);
+			runningFor_ = new PGInterval();
+		}
+		runningFor = runningFor_;
+	}
+	
+	public SqlQueryStat(String query, PGInterval interval, boolean waiting, Long procId) {
+		this.query = query;
+		this.waiting = waiting;
+		this.procId = procId;
+		this.runningFor = interval;
+	}
+
+	public PGInterval getRunningFor() {
+		return runningFor;
+	}
+
+	public String getQuery() {
+		return query;
+	}
+
+	public boolean isWaiting() {
+		return waiting;
+	}
+
+	public Long getProcId() {
+		return procId;
+	}
+	
+	/**
+	 * Process-ID
+	 */
+	private final Long procId;
+
+	private final PGInterval runningFor;
+	private final String query;
+	
+}


Property changes on: trunk/schmitzm-db/src/main/java/de/schmitzm/postgres/SqlQueryStat.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Copied: trunk/schmitzm-db/src/main/java/de/schmitzm/sql/SqlUtil.java (from rev 1818, trunk/schmitzm-db/src/main/java/sql/SqlUtil.java)


Property changes on: trunk/schmitzm-db/src/main/java/de/schmitzm/sql/SqlUtil.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Deleted: trunk/schmitzm-db/src/main/java/postgres/PGUtil.java
===================================================================
--- trunk/schmitzm-db/src/main/java/postgres/PGUtil.java	2012-01-14 20:38:46 UTC (rev 1818)
+++ trunk/schmitzm-db/src/main/java/postgres/PGUtil.java	2012-01-14 20:45:15 UTC (rev 1819)
@@ -1,971 +0,0 @@
-package de.schmitzm.postgres;
-
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.log4j.Logger;
-
-import de.schmitzm.lang.LangUtil;
-
-/**
- * Hilfsmethoden für PostgreSQL. Die Dependency soll nur {@link Connection} sein. In Hibernate kann über #doWork eine
- * {@link Connection} erhalten werden.
- */
-public class PGUtil {
-	static final Logger log = Logger.getLogger(PGUtil.class);
-
-	/**
-	 * PostgreSQL Privilegien die per Grant einer Tabelle zugeordnet werden können.<br/>
-	 * 
-	 * @see http://www.postgresql.org/docs/9.1/static/sql-grant.html
-	 */
-	public enum Privileges {
-		SELECT, INSERT, UPDATE, DELETE, REFERENCES, TEMPORARY, ALL_PRIVILEGES("ALL PRIVILEGES");
-
-		String sql;
-
-		Privileges() {
-			this.sql = super.toString();
-		}
-
-		Privileges(String sql) {
-			this.sql = sql;
-		}
-
-		@Override
-		public String toString() {
-			return this.sql;
-		}
-	}
-
-	/**
-	 * Fügt Privilegien für eine Rolle einer Tabelle hinzu.
-	 * 
-	 * @param tablename
-	 *            Tabellennamen, optional mit "schema.tablename"
-	 * @param targetRole
-	 *            Darf PUBLIC sein, oder Name einer ROLLE.
-	 * @param privileges
-	 *            List der zuzuordnenden Privilegien
-	 * @throws SQLException
-	 */
-	public static void grantPrivilegesOnTable(Connection c, String targetRole, String tablename,
-			Privileges... privileges) throws SQLException {
-		// GRANT SELECT, UPDATE, INSERT ON mytable TO admin;
-		String sql = "GRANT " + LangUtil.stringConcatWithSep(",", (Object[]) privileges) + " ON " + tablename + " TO "
-				+ targetRole;
-		c.createStatement().executeUpdate(sql);
-	}
-
-	/**
-	 * Entfernt Privilegien für eine Rolle von einre Tabelle.
-	 * 
-	 * @param tablename
-	 *            Tabellennamen, optional mit "schema.tablename"
-	 * @param privileges
-	 *            List der zuzuordnenden Privilegien
-	 * @throws SQLException
-	 */
-	public static void revokePrivilegesOnTable(Connection c, String tablename, String targetRole,
-			Privileges... privileges) throws SQLException {
-		// GRANT SELECT, UPDATE, INSERT ON mytable TO admin;
-		String sql = "REVOKE " + LangUtil.stringConcatWithSep(",", (Object[]) privileges) + " ON " + tablename
-				+ " FROM " + targetRole;
-		c.createStatement().executeUpdate(sql);
-	}
-
-	/**
-	 * Erstellt eine neue Rolle
-	 * 
-	 * @param rolename
-	 *            Name der neuen Rolle
-	 * @param inhRoles
-	 *            Rollen in denen die neue Rolle Mitglied ist
-	 */
-	public static void createRole(Connection c, String rolename, String... inhRoles) throws SQLException {
-		String sql = "CREATE ROLE " + rolename;
-		c.createStatement().executeUpdate(sql);
-		for (String inhRole : inhRoles)
-			c.createStatement().executeUpdate("GRANT " + inhRole + " TO " + rolename);
-	}
-
-	/**
-	 * Erstellt eine neue Rolle, wenn diese noch nicht existiert.
-	 * 
-	 * @param rolename
-	 *            Name der neuen Rolle
-	 * @param inhRoles
-	 *            Rollen in denen die neue Rolle Mitglied ist
-	 */
-	public static void createRoleIfNotExists(Connection c, String rolename, String... inhRoles) throws SQLException {
-		if (existsRole(c, rolename))
-			return;
-		createRole(c, rolename, inhRoles);
-	}
-
-	/**
-	 * Querys the <code>geometry_columns</code> table is part of every POSTGIS installation and must/should describe the
-	 * geometry columns and tables.
-	 */
-	static public String[] getColumnsDescribedInGeometryColumnsTable(Statement s) {
-		String[] columns = new String[0];
-		try {
-			ResultSet rs = s.executeQuery("SELECT f_table_name FROM geometry_columns;");
-			try {
-
-				while (rs.next()) {
-					columns = LangUtil.extendArray(columns, rs.getString(1));
-				}
-			} finally {
-				rs.close();
-			}
-		} catch (SQLException e) {
-			log.error(e, e);
-		}
-
-		return columns;
-
-	}
-
-	/**
-	 * Creates or Updates
-	 * 
-	 * @param tableName
-	 * @param geoColumnName
-	 * @param srid
-	 */
-	@Deprecated
-	// tut noch nicht
-	public static void createOrUpdateGeometrysColumnsEntry(String tableName, String geoColumnName, int srid) {
-
-		String createGeometryEntrySQL = "INSERT INTO geometry_columns (f_table_catalog, f_table_schema, f_table_name, f_geometry_column, coord_dimension, srid, \"type\") VALUES ( '', 'public', '"
-				+ tableName + "', '" + geoColumnName + "', 2, " + srid + ",'MULTIPOLYGON' ) LIMIT 1;";
-	}
-
-	// TODO isGeoColumn();
-
-	/**
-	 * @param binding
-	 *            Eine "einfache" Javaklasse, die in PG abgebildet werden soll.
-	 * @return einen PG-spezifischen Datentypenamen für einen Javatyp zurück, z.b. "double precision" für
-	 *         <code>Double.class</code>
-	 */
-	public static String getColTypeName(Class<?> binding) {
-
-		if (binding.isAssignableFrom(Double.class)) {
-			return "double precision"; // eg 'number' at oracle
-		} else if (binding.isAssignableFrom(String.class)) {
-			return "text";
-		} else if (binding.isAssignableFrom(Integer.class)) {
-			return "integer";
-		} else if (binding.isAssignableFrom(Long.class)) {
-			return "bigint";
-		}
-
-		throw new RuntimeException("DB Type mapping for " + binding + " not yet implemented.");
-	}
-
-	/**
-	 * Legt ein Schema an, wenn es vorher nicht existierte.
-	 * 
-	 * @return <code>true</code> wenn das Schema neu angelegt wurde.
-	 */
-	public static boolean createSchemaIfNotExists(Connection c, String schemaname) throws SQLException {
-		if (!existsSchema(c, schemaname)) {
-			c.createStatement().execute("create schema " + schemaname.toLowerCase());
-			return true;
-		}
-		return false;
-	}
-
-	/**
-	 * Liefert <code>true</code> wenn ein Schema mit dem Namen in der PG Datenbank existiert.
-	 */
-	public static boolean existsSchema(Connection c, String schemaname) throws SQLException {
-		String sql = "select 1 from pg_catalog.pg_namespace where nspname = '" + schemaname.toLowerCase() + "'";
-		ResultSet rs = c.createStatement().executeQuery(sql);
-		try {
-			return rs.next();
-		} finally {
-			rs.close();
-		}
-
-	}
-
-	/**
-	 * Liefert eine Liste der Rollen in denen der Übergebenen USER (Login role) ist. <br/>
-	 * Tested with PG 8.4
-	 */
-	public static List<String> listRolesForUser(Connection c, String username) throws SQLException {
-		List<String> roles = new ArrayList<String>();
-		String sql = "select rolname from pg_user join pg_auth_members on (pg_user.usesysid=pg_auth_members.member) join pg_roles on (pg_roles.oid=pg_auth_members.roleid) where pg_user.usename='"
-				+ username.toLowerCase() + "'";
-		ResultSet rs = c.createStatement().executeQuery(sql);
-		try {
-			while (rs.next()) {
-				roles.add(rs.getString(1));
-			}
-		} finally {
-			rs.close();
-		}
-		return roles;
-	}
-
-	/**
-	 * Liefert alle Benutzer der DB zurück.
-	 * 
-	 * @throws SQLException
-	 */
-	public static List<String> listUsers(Connection c) throws SQLException {
-		List<String> roles = new ArrayList<String>();
-		ResultSet rs = c.createStatement().executeQuery("select * from pg_user");
-		try {
-			while (rs.next()) {
-				roles.add(rs.getString(1));
-			}
-		} finally {
-			rs.close();
-		}
-		return roles;
-	}
-
-	/**
-	 * Liste aller Tabellennamen in diesem Schema, ohne die Schemaangabe im Namen. (Also 'anreden' und nicht
-	 * 'public.anreden') <br/>
-	 * Tested with PG 8.4
-	 * 
-	 * @param schemaname
-	 *            if <code>null</code>, <code>public</code> is used.
-	 */
-	public static List<String> listTablesInSchema(Connection c, String schemaname) throws SQLException {
-		List<String> tables = new ArrayList<String>();
-
-		String sql = "select tablename from pg_tables where schemaname = '" + schemaname.toLowerCase() + "'";
-		ResultSet rs = c.createStatement().executeQuery(sql);
-		try {
-			while (rs.next()) {
-				tables.add(rs.getString(1));
-			}
-		} finally {
-			rs.close();
-		}
-		return tables;
-	}
-
-	/**
-	 * Liefert <code>true</code> wenn der Benutzername im DBMS Superuser ist.
-	 */
-	public static boolean isSuperuser(Connection c, String username) throws SQLException {
-		ResultSet rs = c.createStatement().executeQuery(
-				"select usesuper from pg_user where usename = '" + username + "' and usesuper = true");
-		try {
-			if (rs.next()) {
-				return true;
-			}
-		} finally {
-			rs.close();
-		}
-		return false;
-	}
-
-	public static boolean existsRole(Connection c, String rolename) throws SQLException {
-		String sql = "select count(1) from pg_roles where rolname = '" + rolename.toLowerCase() + "'";
-		ResultSet rs = c.createStatement().executeQuery(sql);
-		try {
-			if (rs.next())
-				return rs.getInt(1) > 0;
-		} finally {
-			rs.close();
-		}
-		return false;
-	}
-
-	public static void removeAllPrivilegesFrom(Connection c, String rolename, String tablename) throws SQLException {
-		c.createStatement().executeUpdate(
-				"revoke all on TABLE " + tablename.toLowerCase() + " from " + rolename.toLowerCase() + " cascade");
-	}
-
-	/**
-	 * Löscht eine Rolle wenn sie vorher existiert
-	 */
-	public static void dropRoleIfExists(Connection c, String rolename) throws SQLException {
-		c.createStatement().executeUpdate("drop role if exists " + rolename.toLowerCase());
-	}
-
-	/**
-	 * Löscht einen Trigger wenn er vorher existierte.
-	 * 
-	 * @param c
-	 * @param triggerName
-	 * @param tableName
-	 */
-	public static void dropTriggerIfExists(Connection c, String triggerName, String tableName) throws SQLException {
-		c.createStatement().executeUpdate("drop TRIGGER if exists " + triggerName.toLowerCase() + " ON " + tableName);
-	}
-
-	/**
-	 * 
-	 * @param c
-	 * @param name
-	 *            z.B.: keckformel wird dann zu keckformel()
-	 * @param plCommands
-	 *            z.B.
-	 *            <code>NEW.kpk_kreis = NEW.risiko_soz+NEW.risiko_emo+NEW.risiko_moti +NEW.risiko_spr+NEW.risiko_wohl;</code>
-	 *            OHNE <code>RETURN NEW</code>, das wird automatisch angehangen.
-	 * @throws SQLException
-	 */
-	public static void createOrReplaceTriggerFunction(Connection c, String name, String plCommands) throws SQLException {
-		// System.err.println(plCommands);
-
-		// String sql = "CREATE OR REPLACE FUNCTION " + name + "()" + " RETURNS trigger AS $" + name
-		// + "$\nBEGIN\n?\nRETURN NEW;" + "\nEND;\n$" + name + "$ LANGUAGE 'plpgsql'";
-		// PreparedStatement ps = c.prepareStatement(sql);
-		// ps.setString(0, plCommands);
-		// ps.executeUpdate();
-
-		// String sql = "CREATE OR REPLACE FUNCTION " + name + "()" + " RETURNS trigger AS $" + name + "$\nBEGIN\n "
-		// + plCommands + " \nRETURN NEW;" + "\nEND;\n$" + name + "$ LANGUAGE 'plpgsql'";
-		// c.createStatement().executeUpdate(sql);
-
-		createOrReplaceFunction(c, name, null, "TRIGGER", null, plCommands + "\nRETURN NEW");
-	}
-
-	/**
-	 * 
-	 * @param c
-	 * @param name
-	 *            z.B.: keckformel wird dann zu keckformel()
-	 * @param parameters
-	 *            Parameter der Funcktion, kann <code>null</code> sein.
-	 * @param returns
-	 *            z.B. <code>TRIGGER</code> oder <code>SETOF bigint</code> oder "void"
-	 * @param declare
-	 *            Declare block oder <code>null</code>
-	 * @param plCommands
-	 *            z.B. NEW.kpk_kreis = NEW.risiko_soz+NEW.risiko_emo+NEW.risiko_moti +NEW.risiko_spr+NEW.risiko_wohl;
-	 */
-	public static void createOrReplaceFunction(Connection c, String name, String parameters, String returns,
-			String declare, String plCommands) throws SQLException {
-		// System.err.println(plCommands);
-
-		// String sql = "CREATE OR REPLACE FUNCTION " + name + "()" + " RETURNS trigger AS $" + name
-		// + "$\nBEGIN\n?\nRETURN NEW;" + "\nEND;\n$" + name + "$ LANGUAGE 'plpgsql'";
-		// PreparedStatement ps = c.prepareStatement(sql);
-		// ps.setString(0, plCommands);
-		// ps.executeUpdate();
-
-		parameters = LangUtil.removeWhitespacesToEmpty(parameters);
-		declare = LangUtil.removeWhitespacesToEmpty(declare);
-
-		String sql = "CREATE OR REPLACE FUNCTION " + name + "(" + parameters + ")" + " RETURNS " + returns + " AS $$\n"
-				+ "DECLARE\n" + declare + "\n" + "BEGIN\n " + plCommands + ";" + "\nEND;\n$$ LANGUAGE 'plpgsql'";
-		c.createStatement().executeUpdate(sql);
-	}
-
-	/**
-	 * Erstellt einen <code>FOR EACH ROW EXECUTE PROCEDURE</code> trigger für eine Tabelle
-	 * 
-	 * @param c
-	 * @param triggerName
-	 * @param type
-	 *            z.B. "BEFORE INSERT OR UPDATE"
-	 * @param tableName
-	 * @param plCommands
-	 *            PSQL commands, e.g.<br/>
-	 *            <code>
-	    IF ((TG_OP = 'UPDATE') or (TG_OP = 'INSERT') ) THEN
-            INSERT INTO workqueue values (NEW.id);
-            RETURN NEW;
-        END IF;
-        </code>
-	 */
-	public static void createOrRecreateTrigger(Connection c, String triggerName, String type, String tableName,
-			String plCommands) throws SQLException {
-		dropTriggerIfExists(c, triggerName, tableName);
-		createOrReplaceTriggerFunction(c, triggerName + "_fn", plCommands);
-		c.createStatement().executeUpdate(
-				"CREATE TRIGGER " + triggerName + " " + type + " ON " + tableName + " FOR EACH ROW EXECUTE PROCEDURE "
-						+ triggerName + "_fn" + "()");
-	}
-
-	/**
-	 * @param tableName
-	 *            e.g. 'inseratabfragen_kvps'
-	 * @param columns
-	 *            e.g. 'inseratabfrage_id'
-	 * @param idxNamePostfix
-	 *            e.g. 'idx1'
-	 * @param unique
-	 *            <code>true</code> if the columns are unique. A UNIQUE INDEX will be created.
-	 */
-	public static void addIndex(Connection c, final String tableName, final String columns, String idxPostfix,
-			final boolean unique) throws SQLException {
-		addIndex(c, tableName, columns, idxPostfix, unique, null, null, false, null);
-	}
-
-	/**
-	 * Liefert eine Liste aller Indexnamen die für eine Tabelle existieren. Der Tabellenname wird mit <code>like</code>
-	 * verglichen, darf also <code>%</code> enthalten.<br/>
-	 * Achtung: Diese abfrage ist nicht Schema-Spezifisch. Eine schema. Angabe vor dem tabellennamen wird automatisch
-	 * entfernt.
-	 */
-	public static List<String> listIndexesForTable(Connection c, String tableName) throws SQLException {
-		Statement s = c.createStatement();
-
-		if (tableName.contains("."))
-			tableName = tableName.substring(tableName.indexOf(".") + 1, tableName.length());
-
-		List<String> idxes = new ArrayList<String>();
-
-		// , array_to_string(array_agg(a.attname), ', ') as column_names
-		String sql = "select t.relname as table_name, i.relname as index_name from pg_class t, pg_class i, pg_index ix, pg_attribute a where t.oid = ix.indrelid and i.oid = ix.indexrelid and a.attrelid = t.oid and a.attnum = ANY(ix.indkey) and t.relkind = 'r' and t.relname like '"
-				+ tableName + "' group by t.relname, i.relname order by t.relname, i.relname";
-
-		ResultSet rs = s.executeQuery(sql);
-		try {
-			while (rs.next()) {
-				idxes.add(rs.getString(2));
-			}
-		} finally {
-			rs.close();
-		}
-
-		return idxes;
-
-	}
-
-	/**
-	 * @param tableName
-	 *            e.g. 'inseratabfragen_kvps'
-	 * @param columns
-	 *            e.g. 'inseratabfrage_id'
-	 * @param idxNamePostfix
-	 *            e.g. 'idx1'
-	 * @param unique
-	 *            <code>true</code> if the columns are unique. A UNIQUE INDEX will be created.
-	 * @param tablespace
-	 *            <code>null</code> oder der name des tablespace in dem der Index liegen soll.
-	 * @param type
-	 *            <code>null</code> für DB default oder "hash" oder "btree" oder "gin" etc...
-	 * @param forceRecreationIfExistsAlready
-	 *            wenn <code>true</code> dann werden der Index vorher gedroppt falls er exisitert.
-	 * @param fillFactor
-	 *            Wert von >0. -> 1. Bei .5 wird für den Index doppelt so viel Platz reserviert wie aktuell benötig, um
-	 *            auf weiteres Wachstum der Tabelle ohne Indexfragmentierung reagieren zu können.
-	 */
-	public static void addIndex(Connection c, final String tableName, final String columns, String idxPostfix,
-			final boolean unique, String tablespace, String type, boolean forceRecreationIfExistsAlready,
-			Double fillFactor) throws SQLException {
-		String idxNameWithDot = tableName + "_" + idxPostfix;
-		final String idxName = idxNameWithDot.replace(".", "_");
-
-		// Wenn der Tablename ein Schema mit "schema.name" enthält, dann liefert
-		// listIndexesForTable hier ein schema_table im Index-Namen zurück. Der
-		// "." wird also zu einem "_"
-		for (String existIdxName : listIndexesForTable(c, tableName)) {
-			if (existIdxName.equalsIgnoreCase(idxName.replaceFirst("\\.", "_"))) {
-				// Existiert bereits.
-
-				if (!forceRecreationIfExistsAlready)
-					return;
-
-				log.info("Aufgrund von forceRecreationIfExistsAlready=true wird der Index " + idxNameWithDot
-						+ " jetzt gedroppt.");
-
-				Statement s = c.createStatement();
-
-				// Hier die Schreibweise mit . für schematrennung verwenden
-				final String queryString = "DROP INDEX " + idxNameWithDot;
-				try {
-					s.execute(queryString);
-					c.commit();
-					log.debug("Index dropped: " + queryString);
-				} catch (SQLException e) {
-					c.rollback();
-					Throwable cause = e;
-					if (e.getCause() != null)
-						cause = e.getCause();
-
-					// keine Ausgabe bei: already EXISTs, EXISTiert
-					// bereits,
-					// ...
-					// Ex abfangen, wenn IDX schon existiert
-
-					String msg = cause.getMessage();
-					log.error(e.getLocalizedMessage(), e);
-					return;
-				}
-
-				break;
-
-			}
-		}
-
-		Statement s = c.createStatement();
-
-		if (fillFactor != null && (fillFactor <= 0. || fillFactor > 1.))
-			throw new IllegalArgumentException("fillFactor muss großer 0 und kleinergleich 1 sein.");
-
-		String sqlFillFactor = "";
-		if (fillFactor != null)
-			sqlFillFactor = " WITH (FILLFACTOR=" + (int) (fillFactor * 100) + ") ";
-
-		String sqlTableSpace = (tablespace == null || tablespace.equalsIgnoreCase("null") || !existsTablespace(c, tableName)) ? "" : " TABLESPACE "
-				+ tablespace;
-		
-		
-
-		String sqlUsing = type == null ? "" : " USING " + type;
-
-		final String queryString = "CREATE " + (unique ? "UNIQUE " : "") + "INDEX " + idxName + " ON " + tableName
-				+ sqlUsing + " (" + columns + ") " + sqlFillFactor + sqlTableSpace;
-		try {
-			s.execute(queryString);
-			c.commit();
-			log.info("Neuen Index erstellt: " + queryString);
-		} catch (SQLException e) {
-			c.rollback();
-			Throwable cause = e;
-			if (e.getCause() != null)
-				cause = e.getCause();
-
-			// keine Ausgabe bei: already EXISTs, EXISTiert
-			// bereits,
-			// ...
-			// Ex abfangen, wenn IDX schon existiert
-
-			String msg = cause.getMessage();
-			if (msg.endsWith("already exists") || msg.endsWith("existiert bereits")) {
-				// TO NOTHING, IDX already exists
-				log.info("Index existierte bereits, nicht neuerstellt: " + queryString);
-			} else
-				log.error(e.getLocalizedMessage(), e);
-
-		}
-
-	}
-
-	/**
-	 * Liefert <code>true</code> wenn ein tablespace mit dem Namen existiert.
-	 * @throws SQLException 
-	 */
-	private static boolean existsTablespace(Connection c, String spaceName) throws SQLException {
-		
-		// SELECT count(1) FROM pg_tablespace where spcname = 'spcname';
-		String stmtSql = "SELECT COUNT(*) FROM pg_tablespace where spcname = '"+spaceName+"'";
-
-		PreparedStatement stmt = c.prepareStatement(stmtSql);
-		stmt.execute();
-
-		ResultSet result = stmt.getResultSet();
-		try {
-			int count = 0;
-			if (result.next())
-				count = result.getInt(1);
-
-			return count > 0;
-		} finally {
-			result.close();
-			stmt.close();
-		}
-
-	}
-
-	/**
-	 * Fügt einen Benutzer zu einer Rolle hinzu. Wenn der benutzer bereits in der Rolle enthalten ist, wird keine
-	 * Exception geschmisssen.
-	 * 
-	 * @throws SQLException
-	 */
-	public static void grantRoleToUser(Connection c, String rolename, String username) throws SQLException {
-		c.createStatement().executeUpdate("GRANT " + rolename + " TO " + username);
-	}
-
-	/**
-	 * Der : (Doppelpunkt) hat in PSQL eine besondere Bedeutung. Er wind mit dieser methode escaped. Diese Methode
-	 * sollte mit <code>like E'"+PGUtil.escape(...)+"'</code> verwendet werden.
-	 */
-	public static String escape(String key) {
-		key = key.replaceAll(":", "\\:");
-		return key;
-	}
-
-	/**
-	 * Liefert die Anzahl der offenen Sessions zur Datenbank.
-	 * 
-	 * @param c
-	 *            DB-Verbindung
-	 * @param dbName
-	 *            Name der Datenbank fuer die die Sessions gezaehlt werden (kann {@code null} sein)
-	 * @param userName
-	 *            Name des Users fuer den die Sessions gezaehlt werden (kann {@code null} sein)
-	 */
-	public static int getOpenSessionCount(Connection c, String dbName, String userName) throws SQLException {
-		return getOpenSessionCount(c, dbName, userName, null);
-	}
-
-	/**
-	 * Liefert die Anzahl der offenen Sessions zur Datenbank.
-	 * 
-	 * @param c
-	 *            DB-Verbindung
-	 * @param dbName
-	 *            Name der Datenbank fuer die die Sessions gezaehlt werden (kann {@code null} sein)
-	 * @param userName
-	 *            Name des Users fuer den die Sessions gezaehlt werden (kann {@code null} sein)
-	 * @param queryLike
-	 *            like-Beindung auf die Query die in der Session ausgeführt wird, oder <code>null</code>
-	 */
-	public static int getOpenSessionCount(Connection c, String dbName, String userName, String queryLike)
-			throws SQLException {
-		String stmtSql = "SELECT COUNT(*) FROM pg_stat_activity WHERE TRUE";
-
-		if (dbName != null)
-			stmtSql += " AND datname = ?";
-		if (userName != null)
-			stmtSql += " AND usename = ?";
-		if (queryLike != null) {
-			stmtSql += " AND current_query like '" + queryLike + "'";
-		}
-
-		PreparedStatement stmt = c.prepareStatement(stmtSql);
-		if (dbName != null)
-			stmt.setString(1, dbName);
-		if (userName != null)
-			stmt.setString(2, userName);
-		stmt.execute();
-
-		ResultSet result = stmt.getResultSet();
-		try {
-			int count = 0;
-			if (result.next())
-				count = result.getInt(1);
-
-			return count;
-		} finally {
-			result.close();
-			stmt.close();
-		}
-	}
-
-	/**
-	 * Liefert <code>true</code> wenn eine Spalte mit dem Namen in der angegebenen Tabelle existiert. Die Tablle darf
-	 * optional mit "schema." prefixiert werden.
-	 */
-	public static boolean existsColumn(Connection c, String tableName, String columnName) throws SQLException {
-
-		String schema = "public";
-
-		if (tableName.contains(".")) {
-			final String[] split = tableName.split("\\.");
-			schema = split[0];
-			tableName = split[1];
-		}
-
-		ResultSet nativeCheckExistsColumnQuery = c.createStatement().executeQuery(
-				"SELECT * FROM information_schema.COLUMNS WHERE COLUMN_NAME = '" + columnName.toLowerCase()
-						+ "' AND TABLE_NAME='" + tableName + "' AND TABLE_SCHEMA='" + schema + "';");
-		return nativeCheckExistsColumnQuery.next();
-	}
-
-	/**
-	 * Existiert ein relationsname als View?
-	 * 
-	 * @param viewName
-	 *            Darf eine Schemaangabe mit . Trenner enthalten.
-	 * @throws SQLException
-	 */
-	public static boolean existsView(Connection c, String viewName) throws SQLException {
-
-		String schema = "public";
-
-		if (viewName.contains(".")) {
-			final String[] split = viewName.split("\\.");
-			schema = split[0];
-			viewName = split[1];
-		}
-
-		final String checkView = "SELECT * FROM information_schema.VIEWS where table_schema = '" + schema
-				+ "' and table_name = '" + viewName + "' LIMIT 1";
-		ResultSet rs = c.createStatement().executeQuery(checkView);
-
-		try {
-			return rs.next();
-		} finally {
-			rs.close();
-		}
-	}
-
-	public static void dropViewIfExists(Connection c, String viewName) throws SQLException {
-		final String dropView = "DROP VIEW IF EXISTS " + viewName;
-		c.createStatement().executeUpdate(dropView);
-	}
-
-	/**
-	 * Liefert eine Liste der aktuell laufenden Queries und ihrere Laufzeiten zurück. Der 2. Teil der Rückgabepaare ist
-	 * ein String der einem PG Interval entspricht. Dieses kann mit der Klasse PGInterval geparst werden.<br/>
-	 * 
-	 * @param datName
-	 *            <code>null</code> oder der Datenbankname, auf den die Abfrage gefiltert werden soll.
-	 * 
-	 * @param minSecondsRunning
-	 *            <code>null</code> oder die zurückgegebenen Anfragen müssen mindestens soviele Sekunden schon laufen.
-	 */
-	static public List<String[]> listQueries(Connection c, String datName, Integer minSecondsRunning)
-			throws SQLException {
-		ArrayList<String[]> result = new ArrayList<String[]>();
-
-		String where = "where current_query not like '%IDLE%' ";
-
-		if (datName != null)
-			where += " and datname like '" + datName + "'";
-
-		if (minSecondsRunning != null) {
-			if (minSecondsRunning < 0)
-				throw new IllegalStateException();
-
-			where += " and age (now(),query_start) >= interval '" + minSecondsRunning + " second' ";
-		}
-
-		final String sql = "select current_query, age (now(),query_start) as qage, waiting, procpid from pg_stat_activity "
-				+ where + " order by qage desc";
-		ResultSet rs = c.createStatement().executeQuery(sql);
-
-		try {
-			while (rs.next()) {
-				String q = rs.getString(1);
-				String since = rs.getString(2);
-				String waiting = rs.getString(3);
-				String waiting = rs.getString(3);
-
-				result.add(new String[] { q, since, waiting });
-			}
-
-		} finally {
-			rs.close();
-		}
-		return result;
-	}
-
-	/**
-	 * Tablename der optinal als das Schema enthalten darf.
-	 */
-	public static boolean removeColumn(Connection c, String tableName, String columnName) throws SQLException {
-
-		// Das eigentliche erstellen der neuen Spalte
-		String queryString = "ALTER TABLE " + tableName + " DROP COLUMN " + columnName;
-
-		// System.out.println(queryString);
-
-		int result = c.createStatement().executeUpdate(queryString);
-
-		if (result != 0) {
-			// JRegDBUtils.log.error(queryString + " returned not 0 = " +
-			// result);
-			return false;
-		}
-		return true;
-	}
-
-	/**
-	 * Liefert die COLUMN-NAMES eines PKs einer Tabelle
-	 * 
-	 * @param dbc
-	 *            Connection to Postgressql Database
-	 * @param tableName
-	 *            darf Schemanamen enthalten.
-	 * 
-	 * @return Primary Key. <code>NULL</code> if empty
-	 */
-	public static String getPrimaryKey(Connection dbc, String tableName) throws SQLException {
-
-		String schema = "public";
-		if (tableName.contains(".")) {
-			final String[] split = tableName.split("\\.");
-			schema = split[0];
-			tableName = split[1];
-		}
-
-		Statement s = dbc.createStatement();
-		ResultSet rs = s
-				.executeQuery("select distinct(column_name) from INFORMATION_SCHEMA.KEY_COLUMN_USAGE a,INFORMATION_SCHEMA.TABLE_CONSTRAINTS b where constraint_type = 'PRIMARY KEY' and a.table_name='"
-						+ tableName + "' and a.table_schema='" + schema + "';");
-
-		String pk = "";
-		try {
-
-			while (rs.next()) {
-				pk += rs.getString("column_name");
-			}
-
-		} finally {
-			rs.close();
-		}
-
-		if (pk.endsWith(","))
-			pk = pk.substring(0, pk.length() - 1);
-
-		return pk.isEmpty() ? null : pk;
-
-	}
-
-	/**
-	 * Returns cardinality of column in table
-	 */
-	public long getCardinality(Connection dbc, String tableName, String column) throws SQLException {
-		String sql = "select count( DISTINCT " + "(" + column + ")" + ") " + "from " + tableName;
-		ResultSet countRs = dbc.createStatement().executeQuery(sql);
-		try {
-			countRs.next();
-			return ((Number) countRs.getLong(1)).longValue();
-		} finally {
-			countRs.close();
-		}
-	}
-
-	public static boolean isIntColumn(Connection c, String tableName, String columnName) throws SQLException {
-		String schema = "public";
-		if (tableName.contains(".")) {
-			final String[] split = tableName.split("\\.");
-			schema = split[0];
-			tableName = split[1];
-		}
-
-		Statement s = c.createStatement();
-		ResultSet rs = s.executeQuery("SELECT data_type FROM information_schema.COLUMNS WHERE COLUMN_NAME = '"
-				+ columnName.toLowerCase() + "' AND TABLE_NAME='" + tableName + "' AND TABLE_SCHEMA='" + schema + "';");
-		try {
-
-			rs.next();
-			String typeDef = rs.getString(1);
-			Boolean isNumeric = false;
-			isNumeric |= typeDef.startsWith("numeric");
-
-			return isNumeric;
-		} finally {
-			rs.close();
-		}
-	}
-
-	/**
-	 * Typischer Weise POSTGIS, wenn man sonst nichts anderen installiert hat.
-	 */
-	public static boolean isUserDefinedColumn(Connection c, String tableName, String columnName) throws SQLException {
-
-		String schema = "public";
-		if (tableName.contains(".")) {
-			final String[] split = tableName.split("\\.");
-			schema = split[0];
-			tableName = split[1];
-		}
-
-		Statement s = c.createStatement();
-		ResultSet rs = s.executeQuery("SELECT data_type FROM information_schema.COLUMNS WHERE COLUMN_NAME = '"
-				+ columnName.toLowerCase() + "' AND TABLE_NAME='" + tableName + "' AND TABLE_SCHEMA='" + schema + "';");
-		rs.next();
-		String typeDef = rs.getString(1);
-		return typeDef.toUpperCase().startsWith("USER-DEFINED");
-	}
-
-	public static boolean isTextColumn(Connection c, String tableName, String columnName) throws SQLException {
-
-		String schema = "public";
-		if (tableName.contains(".")) {
-			final String[] split = tableName.split("\\.");
-			schema = split[0];
-			tableName = split[1];
-		}
-
-		Statement s = c.createStatement();
-		ResultSet rs = s.executeQuery("SELECT data_type FROM information_schema.COLUMNS WHERE COLUMN_NAME = '"
-				+ columnName.toLowerCase() + "' AND TABLE_NAME='" + tableName + "' AND TABLE_SCHEMA='" + schema + "';");
-		try {
-			rs.next();
-			String typeDef = rs.getString(1);
-			Boolean isText = false;
-			isText |= typeDef.startsWith("text");
-			isText |= typeDef.startsWith("character");
-
-			return isText;
-		} finally {
-			rs.close();
-		}
-	}
-
-	/**
-	 * Creates a new Column.
-	 * 
-	 * @param dbc
-	 * @param tableName
-	 * @param columnName
-	 * @param colTypeName
-	 * @param comment
-	 * @return
-	 * @throws SQLException
-	 */
-	public static boolean addColumn(Connection dbc, String tableName, String columnName, String colTypeName,
-			String comment) throws SQLException {
-
-		if (dbc == null)
-			throw new IllegalStateException("Es besteht keine Datenbankverbindung!");
-
-		Statement s = dbc.createStatement();
-
-		if (existsColumn(dbc, tableName, columnName)) {
-			return false;
-		}
-
-		// Das eigentliche erstellen der neuen Spalte
-		String queryString = "ALTER TABLE " + tableName + " ADD " + columnName + " " + colTypeName;
-
-		// JRegDBUtils.log.debug(queryString);
-
-		int result = s.executeUpdate(queryString);
-
-		if (result != 0) {
-			return false;
-		}
-
-		if (comment != null && !comment.isEmpty()) {
-			queryString = "COMMENT ON COLUMN " + tableName + "." + columnName + " IS '" + comment + "';";
-		}
-
-		s.close();
-
-		return true;
-	}
-
-	/**
-	 * Liefert alle Spalten einer Tabelle
-	 */
-	public static ArrayList<String> getAllColumnsOf(Connection dbc, String tableName) throws SQLException {
-		String schema = "public";
-		if (tableName.contains(".")) {
-			final String[] split = tableName.split("\\.");
-			schema = split[0];
-			tableName = split[1];
-		}
-
-		ArrayList<String> cols = new ArrayList<String>();
-
-		// String tableName = PropertyUtils.getDbTableName(i);
-
-		String sql = "SELECT column_name FROM information_schema.COLUMNS WHERE TABLE_NAME = '" + tableName
-				+ "' and TABLE_SCHEMA = '" + schema + "';";
-
-		ResultSet colsRs = dbc.createStatement().executeQuery(sql);
-		try {
-			while (colsRs.next())
-				cols.add(colsRs.getString(1));
-		} finally {
-			colsRs.close();
-		}
-		return cols;
-	}
-
-}

Deleted: trunk/schmitzm-db/src/main/java/postgres/SqlQueryStat.java
===================================================================
--- trunk/schmitzm-db/src/main/java/postgres/SqlQueryStat.java	2012-01-14 20:38:46 UTC (rev 1818)
+++ trunk/schmitzm-db/src/main/java/postgres/SqlQueryStat.java	2012-01-14 20:45:15 UTC (rev 1819)
@@ -1,59 +0,0 @@
-package de.schmitzm.postgres;
-
-import java.sql.SQLException;
-
-import org.apache.log4j.Logger;
-import org.postgresql.util.PGInterval;
-
-/**
- * Beschreibt eine laufende SQL Aktion.
- * 
- * TODO schmitzm-pg
- */
-public class SqlQueryStat {
-
-	final static Logger log = Logger.getLogger(SqlQueryStat.class);
-	private final boolean waiting;
-
-	public SqlQueryStat(String query, String interval, boolean waiting, Long procId) {
-		this.query = query;
-		this.waiting = waiting;
-		this.procId = procId;
-		PGInterval runningFor_;
-		try {
-			runningFor_ = new PGInterval(interval);
-		} catch (SQLException e) {
-			log.error(e);
-			runningFor_ = new PGInterval();
-		}
-		runningFor = runningFor_;
-	}
-
-	public PGInterval getRunningFor() {
-		return runningFor;
-	}
-
-	public String getQuery() {
-		return query;
-	}
-
-	public boolean isWaiting() {
-		return waiting;
-	}
-
-	public Long getProcId() {
-		return procId;
-	}
-
-	public void setProcId(Long procId) {
-		this.procId = procId;
-	}
-
-	private final PGInterval runningFor;
-	private final String query;
-	
-	/**
-	 * Process-ID
-	 */
-	private final Long procId;
-}

Deleted: trunk/schmitzm-db/src/main/java/sql/SqlUtil.java
===================================================================
--- trunk/schmitzm-db/src/main/java/sql/SqlUtil.java	2012-01-14 20:38:46 UTC (rev 1818)
+++ trunk/schmitzm-db/src/main/java/sql/SqlUtil.java	2012-01-14 20:45:15 UTC (rev 1819)
@@ -1,61 +0,0 @@
-package de.schmitzm.sql;
-
-/**
- * Utilityklasse mit statisch Methoden für SQL.
- */
-public class SqlUtil {
-
-    /**
-     * VZ steht füer VergleichsZustände un beschreibt was beim vergleich zweier
-     * attribute (.z.b. Hausnummer) alles rauskommen kann, wenn NULL gesondert
-     * betrachtet wird.
-     */
-    public enum VZ {
-        GLEICH, NULL1, NULL12, NULL2, UNGLEICH;
-
-        /**
-         * Drückt diesen Vergleichszustand als SQL aus.
-         */
-        public String toSql(String colName1, String colName2) {
-
-            switch (this) {
-            /**
-             * Beide column haben den selben wert
-             */
-                case GLEICH:
-                    return "( (" + colName1 + " IS NOT NULL) AND (" + colName2
-                            + " IS NOT NULL) AND (" + colName1 + " LIKE "
-                            + colName2 + ") )";
-                    /**
-                     * Beide column sind nicht null und haben nicht den selben wert
-                     */
-                case UNGLEICH:
-                    return "( (" + colName1 + " IS NOT NULL) AND (" + colName2
-                            + " IS NOT NULL) AND (NOT " + colName1 + " LIKE "
-                            + colName2 + ") )";
-                    /**
-                     * die erste col is null, die zweite nicht
-                     */
-                case NULL1:
-                    return "( (" + colName1 + " IS NOT NULL) AND (" + colName2
-                            + " IS NULL)  )";
-                    /**
-                     * die zweite col is null, die erste nicht
-                     */
-                case NULL2:
-                    return "( (" + colName1 + " IS NOT NULL) AND (" + colName2
-                            + " IS NULL)  )";
-                    /**
-                     * beide col sind null
-                     */
-                case NULL12:
-                    return "( (" + colName1 + " IS NULL) AND (" + colName2
-                            + " IS NULL)  )";
-            }
-
-            throw new IllegalStateException("Kann " + this
-                    + " nicht in SQL convertieren");
-        }
-    }
-
-}
\ No newline at end of file



More information about the Schmitzm-commits mailing list