Commits

tbrugz  committed 6db1613

sqlpivot: initial version

  • Participants
  • Parent commits ddfe677

Comments (0)

Files changed (5)

File src_pivot/tbrugz/sqldump/pivot/PivotConnection.java

+package tbrugz.sqldump.pivot;
+
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.CallableStatement;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.NClob;
+import java.sql.PreparedStatement;
+import java.sql.SQLClientInfoException;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.SQLXML;
+import java.sql.Savepoint;
+import java.sql.Statement;
+import java.sql.Struct;
+import java.util.Map;
+import java.util.Properties;
+
+public class PivotConnection implements Connection {
+	
+	final Connection conn;
+
+	public PivotConnection(Connection conn) {
+		this.conn = conn;
+	}
+	
+	public <T> T unwrap(Class<T> iface) throws SQLException {
+		return conn.unwrap(iface);
+	}
+
+	public boolean isWrapperFor(Class<?> iface) throws SQLException {
+		return conn.isWrapperFor(iface);
+	}
+
+	//TODO
+	public Statement createStatement() throws SQLException {
+		return new PivotStatement<Statement>(conn.createStatement());
+	}
+
+	//TODO
+	public PreparedStatement prepareStatement(String sql) throws SQLException {
+		return new PivotPreparedStatement(conn.prepareStatement(sql), sql);
+	}
+
+	public CallableStatement prepareCall(String sql) throws SQLException {
+		return conn.prepareCall(sql);
+	}
+
+	//???
+	public String nativeSQL(String sql) throws SQLException {
+		return conn.nativeSQL(sql);
+	}
+
+	public void setAutoCommit(boolean autoCommit) throws SQLException {
+		conn.setAutoCommit(autoCommit);
+	}
+
+	public boolean getAutoCommit() throws SQLException {
+		return conn.getAutoCommit();
+	}
+
+	public void commit() throws SQLException {
+		conn.commit();
+	}
+
+	public void rollback() throws SQLException {
+		conn.rollback();
+	}
+
+	public void close() throws SQLException {
+		conn.close();
+	}
+
+	public boolean isClosed() throws SQLException {
+		return conn.isClosed();
+	}
+
+	public DatabaseMetaData getMetaData() throws SQLException {
+		return conn.getMetaData();
+	}
+
+	public void setReadOnly(boolean readOnly) throws SQLException {
+		conn.setReadOnly(readOnly);
+	}
+
+	public boolean isReadOnly() throws SQLException {
+		return conn.isReadOnly();
+	}
+
+	public void setCatalog(String catalog) throws SQLException {
+		conn.setCatalog(catalog);
+	}
+
+	public String getCatalog() throws SQLException {
+		return conn.getCatalog();
+	}
+
+	public void setTransactionIsolation(int level) throws SQLException {
+		conn.setTransactionIsolation(level);
+	}
+
+	public int getTransactionIsolation() throws SQLException {
+		return conn.getTransactionIsolation();
+	}
+
+	public SQLWarning getWarnings() throws SQLException {
+		return conn.getWarnings();
+	}
+
+	public void clearWarnings() throws SQLException {
+		conn.clearWarnings();
+	}
+
+	//TODO
+	public Statement createStatement(int resultSetType, int resultSetConcurrency)
+			throws SQLException {
+		return new PivotStatement<Statement>(conn.createStatement(resultSetType, resultSetConcurrency));
+	}
+
+	//TODO
+	public PreparedStatement prepareStatement(String sql, int resultSetType,
+			int resultSetConcurrency) throws SQLException {
+		return new PivotPreparedStatement(conn.prepareStatement(sql, resultSetType, resultSetConcurrency), sql);
+	}
+
+	public CallableStatement prepareCall(String sql, int resultSetType,
+			int resultSetConcurrency) throws SQLException {
+		return conn.prepareCall(sql, resultSetType, resultSetConcurrency);
+	}
+
+	public Map<String, Class<?>> getTypeMap() throws SQLException {
+		return conn.getTypeMap();
+	}
+
+	public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
+		conn.setTypeMap(map);
+	}
+
+	public void setHoldability(int holdability) throws SQLException {
+		conn.setHoldability(holdability);
+	}
+
+	public int getHoldability() throws SQLException {
+		return conn.getHoldability();
+	}
+
+	public Savepoint setSavepoint() throws SQLException {
+		return conn.setSavepoint();
+	}
+
+	public Savepoint setSavepoint(String name) throws SQLException {
+		return conn.setSavepoint(name);
+	}
+
+	public void rollback(Savepoint savepoint) throws SQLException {
+		conn.rollback(savepoint);
+	}
+
+	public void releaseSavepoint(Savepoint savepoint) throws SQLException {
+		conn.releaseSavepoint(savepoint);
+	}
+
+	//TODO
+	public Statement createStatement(int resultSetType,
+			int resultSetConcurrency, int resultSetHoldability)
+			throws SQLException {
+		return new PivotStatement<Statement>(conn.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability));
+	}
+
+	//TODO
+	public PreparedStatement prepareStatement(String sql, int resultSetType,
+			int resultSetConcurrency, int resultSetHoldability)
+			throws SQLException {
+		return new PivotPreparedStatement(conn.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability), sql);
+	}
+
+	public CallableStatement prepareCall(String sql, int resultSetType,
+			int resultSetConcurrency, int resultSetHoldability)
+			throws SQLException {
+		return conn.prepareCall(sql, resultSetType, resultSetConcurrency,
+				resultSetHoldability);
+	}
+
+	//TODO
+	public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
+			throws SQLException {
+		return new PivotPreparedStatement(conn.prepareStatement(sql, autoGeneratedKeys), sql);
+	}
+
+	//TODO
+	public PreparedStatement prepareStatement(String sql, int[] columnIndexes)
+			throws SQLException {
+		return new PivotPreparedStatement(conn.prepareStatement(sql, columnIndexes), sql);
+	}
+
+	//TODO
+	public PreparedStatement prepareStatement(String sql, String[] columnNames)
+			throws SQLException {
+		return new PivotPreparedStatement(conn.prepareStatement(sql, columnNames), sql);
+	}
+
+	public Clob createClob() throws SQLException {
+		return conn.createClob();
+	}
+
+	public Blob createBlob() throws SQLException {
+		return conn.createBlob();
+	}
+
+	public NClob createNClob() throws SQLException {
+		return conn.createNClob();
+	}
+
+	public SQLXML createSQLXML() throws SQLException {
+		return conn.createSQLXML();
+	}
+
+	public boolean isValid(int timeout) throws SQLException {
+		return conn.isValid(timeout);
+	}
+
+	public void setClientInfo(String name, String value)
+			throws SQLClientInfoException {
+		conn.setClientInfo(name, value);
+	}
+
+	public void setClientInfo(Properties properties)
+			throws SQLClientInfoException {
+		conn.setClientInfo(properties);
+	}
+
+	public String getClientInfo(String name) throws SQLException {
+		return conn.getClientInfo(name);
+	}
+
+	public Properties getClientInfo() throws SQLException {
+		return conn.getClientInfo();
+	}
+
+	public Array createArrayOf(String typeName, Object[] elements)
+			throws SQLException {
+		return conn.createArrayOf(typeName, elements);
+	}
+
+	public Struct createStruct(String typeName, Object[] attributes)
+			throws SQLException {
+		return conn.createStruct(typeName, attributes);
+	}
+
+}

File src_pivot/tbrugz/sqldump/pivot/PivotPreparedStatement.java

+package tbrugz.sqldump.pivot;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.NClob;
+import java.sql.ParameterMetaData;
+import java.sql.PreparedStatement;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLXML;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+
+import tbrugz.sqldump.resultset.pivot.PivotResultSet;
+
+public class PivotPreparedStatement extends PivotStatement<PreparedStatement> implements PreparedStatement {
+
+	//final PreparedStatement statement;
+	final String sql;
+
+	public PivotPreparedStatement(PreparedStatement statement, String sql) {
+		super(statement);
+		this.sql = sql;
+		//this.statement = statement;
+	}
+	
+	//XXX
+	public ResultSet executeQuery() throws SQLException {
+		PivotQueryParser parser = new PivotQueryParser(sql);
+		return new PivotResultSet(statement.executeQuery(), parser.colsNotToPivot, parser.colsToPivot, true);
+		//return statement.executeQuery();
+	}
+
+	public int executeUpdate() throws SQLException {
+		return statement.executeUpdate();
+	}
+
+	public void setNull(int parameterIndex, int sqlType) throws SQLException {
+		statement.setNull(parameterIndex, sqlType);
+	}
+
+	public void setBoolean(int parameterIndex, boolean x) throws SQLException {
+		statement.setBoolean(parameterIndex, x);
+	}
+
+	public void setMaxFieldSize(int max) throws SQLException {
+		statement.setMaxFieldSize(max);
+	}
+
+	public void setByte(int parameterIndex, byte x) throws SQLException {
+		statement.setByte(parameterIndex, x);
+	}
+
+	public void setShort(int parameterIndex, short x) throws SQLException {
+		statement.setShort(parameterIndex, x);
+	}
+
+	public void setInt(int parameterIndex, int x) throws SQLException {
+		statement.setInt(parameterIndex, x);
+	}
+
+	public void setMaxRows(int max) throws SQLException {
+		statement.setMaxRows(max);
+	}
+
+	public void setLong(int parameterIndex, long x) throws SQLException {
+		statement.setLong(parameterIndex, x);
+	}
+
+	public void setEscapeProcessing(boolean enable) throws SQLException {
+		statement.setEscapeProcessing(enable);
+	}
+
+	public void setFloat(int parameterIndex, float x) throws SQLException {
+		statement.setFloat(parameterIndex, x);
+	}
+
+	public void setDouble(int parameterIndex, double x) throws SQLException {
+		statement.setDouble(parameterIndex, x);
+	}
+
+	public void setQueryTimeout(int seconds) throws SQLException {
+		statement.setQueryTimeout(seconds);
+	}
+
+	public void setBigDecimal(int parameterIndex, BigDecimal x)
+			throws SQLException {
+		statement.setBigDecimal(parameterIndex, x);
+	}
+
+	public void setString(int parameterIndex, String x) throws SQLException {
+		statement.setString(parameterIndex, x);
+	}
+
+	public void setBytes(int parameterIndex, byte[] x) throws SQLException {
+		statement.setBytes(parameterIndex, x);
+	}
+
+	public void setDate(int parameterIndex, Date x) throws SQLException {
+		statement.setDate(parameterIndex, x);
+	}
+
+	public void setCursorName(String name) throws SQLException {
+		statement.setCursorName(name);
+	}
+
+	public void setTime(int parameterIndex, Time x) throws SQLException {
+		statement.setTime(parameterIndex, x);
+	}
+
+	public void setTimestamp(int parameterIndex, Timestamp x)
+			throws SQLException {
+		statement.setTimestamp(parameterIndex, x);
+	}
+
+	public void setAsciiStream(int parameterIndex, InputStream x, int length)
+			throws SQLException {
+		statement.setAsciiStream(parameterIndex, x, length);
+	}
+
+	@SuppressWarnings("deprecation")
+	public void setUnicodeStream(int parameterIndex, InputStream x, int length)
+			throws SQLException {
+		statement.setUnicodeStream(parameterIndex, x, length);
+	}
+
+	public void setBinaryStream(int parameterIndex, InputStream x, int length)
+			throws SQLException {
+		statement.setBinaryStream(parameterIndex, x, length);
+	}
+
+	public void clearParameters() throws SQLException {
+		statement.clearParameters();
+	}
+
+	public void setObject(int parameterIndex, Object x, int targetSqlType)
+			throws SQLException {
+		statement.setObject(parameterIndex, x, targetSqlType);
+	}
+
+	public void setObject(int parameterIndex, Object x) throws SQLException {
+		statement.setObject(parameterIndex, x);
+	}
+
+	public void addBatch(String sql) throws SQLException {
+		statement.addBatch(sql);
+	}
+
+	public void clearBatch() throws SQLException {
+		statement.clearBatch();
+	}
+
+	public boolean execute() throws SQLException {
+		return statement.execute();
+	}
+
+	public void addBatch() throws SQLException {
+		statement.addBatch();
+	}
+
+	public void setCharacterStream(int parameterIndex, Reader reader, int length)
+			throws SQLException {
+		statement.setCharacterStream(parameterIndex, reader, length);
+	}
+
+	public void setRef(int parameterIndex, Ref x) throws SQLException {
+		statement.setRef(parameterIndex, x);
+	}
+
+	public void setBlob(int parameterIndex, Blob x) throws SQLException {
+		statement.setBlob(parameterIndex, x);
+	}
+
+	public void setClob(int parameterIndex, Clob x) throws SQLException {
+		statement.setClob(parameterIndex, x);
+	}
+
+	public boolean getMoreResults(int current) throws SQLException {
+		return statement.getMoreResults(current);
+	}
+
+	public void setArray(int parameterIndex, Array x) throws SQLException {
+		statement.setArray(parameterIndex, x);
+	}
+
+	//XXX ??
+	public ResultSetMetaData getMetaData() throws SQLException {
+		return statement.getMetaData();
+	}
+
+	public void setDate(int parameterIndex, Date x, Calendar cal)
+			throws SQLException {
+		statement.setDate(parameterIndex, x, cal);
+	}
+
+	public void setTime(int parameterIndex, Time x, Calendar cal)
+			throws SQLException {
+		statement.setTime(parameterIndex, x, cal);
+	}
+
+	public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal)
+			throws SQLException {
+		statement.setTimestamp(parameterIndex, x, cal);
+	}
+
+	public void setNull(int parameterIndex, int sqlType, String typeName)
+			throws SQLException {
+		statement.setNull(parameterIndex, sqlType, typeName);
+	}
+
+	public void setURL(int parameterIndex, URL x) throws SQLException {
+		statement.setURL(parameterIndex, x);
+	}
+
+	public ParameterMetaData getParameterMetaData() throws SQLException {
+		return statement.getParameterMetaData();
+	}
+
+	public void setRowId(int parameterIndex, RowId x) throws SQLException {
+		statement.setRowId(parameterIndex, x);
+	}
+
+	public void setNString(int parameterIndex, String value)
+			throws SQLException {
+		statement.setNString(parameterIndex, value);
+	}
+
+	public void setNCharacterStream(int parameterIndex, Reader value,
+			long length) throws SQLException {
+		statement.setNCharacterStream(parameterIndex, value, length);
+	}
+
+	public void setNClob(int parameterIndex, NClob value) throws SQLException {
+		statement.setNClob(parameterIndex, value);
+	}
+
+	public void setClob(int parameterIndex, Reader reader, long length)
+			throws SQLException {
+		statement.setClob(parameterIndex, reader, length);
+	}
+
+	public void setBlob(int parameterIndex, InputStream inputStream, long length)
+			throws SQLException {
+		statement.setBlob(parameterIndex, inputStream, length);
+	}
+
+	public void setNClob(int parameterIndex, Reader reader, long length)
+			throws SQLException {
+		statement.setNClob(parameterIndex, reader, length);
+	}
+
+	public void setSQLXML(int parameterIndex, SQLXML xmlObject)
+			throws SQLException {
+		statement.setSQLXML(parameterIndex, xmlObject);
+	}
+
+	public void setObject(int parameterIndex, Object x, int targetSqlType,
+			int scaleOrLength) throws SQLException {
+		statement.setObject(parameterIndex, x, targetSqlType, scaleOrLength);
+	}
+
+	public void setAsciiStream(int parameterIndex, InputStream x, long length)
+			throws SQLException {
+		statement.setAsciiStream(parameterIndex, x, length);
+	}
+
+	public void setBinaryStream(int parameterIndex, InputStream x, long length)
+			throws SQLException {
+		statement.setBinaryStream(parameterIndex, x, length);
+	}
+
+	public void setCharacterStream(int parameterIndex, Reader reader,
+			long length) throws SQLException {
+		statement.setCharacterStream(parameterIndex, reader, length);
+	}
+
+	public void setAsciiStream(int parameterIndex, InputStream x)
+			throws SQLException {
+		statement.setAsciiStream(parameterIndex, x);
+	}
+
+	public void setBinaryStream(int parameterIndex, InputStream x)
+			throws SQLException {
+		statement.setBinaryStream(parameterIndex, x);
+	}
+
+	public void setCharacterStream(int parameterIndex, Reader reader)
+			throws SQLException {
+		statement.setCharacterStream(parameterIndex, reader);
+	}
+
+	public void setNCharacterStream(int parameterIndex, Reader value)
+			throws SQLException {
+		statement.setNCharacterStream(parameterIndex, value);
+	}
+
+	public void setClob(int parameterIndex, Reader reader) throws SQLException {
+		statement.setClob(parameterIndex, reader);
+	}
+
+	public void setBlob(int parameterIndex, InputStream inputStream)
+			throws SQLException {
+		statement.setBlob(parameterIndex, inputStream);
+	}
+
+	public void setNClob(int parameterIndex, Reader reader) throws SQLException {
+		statement.setNClob(parameterIndex, reader);
+	}
+	
+}

File src_pivot/tbrugz/sqldump/pivot/PivotQueryParser.java

+package tbrugz.sqldump.pivot;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class PivotQueryParser {
+
+	/*static PivotQueryParser parser = new PivotQueryParser();
+	
+	public static PivotQueryParser instance() {
+		return parser;
+	}
+	
+	public ResultSet parse(String sql) {
+		return null;
+	}*/
+	
+	static final String PATTERN_PIVOT_CLAUSE_STR = "/\\*\\s*pivot\\s+(.*)\\s+nonpivot\\s+(.*)\\s*\\*/";
+	static final Pattern PATTERN_PIVOT_CLAUSE = Pattern.compile(PATTERN_PIVOT_CLAUSE_STR, Pattern.CASE_INSENSITIVE);
+
+	final Map<String, Comparable> colsToPivot;
+	final List<String> colsNotToPivot;
+	
+	public PivotQueryParser(String sql) {
+		Matcher m = PATTERN_PIVOT_CLAUSE.matcher(sql);
+		boolean found = m.find();
+		if(!found) {
+			colsToPivot = null;
+			colsNotToPivot = null;
+			return;
+		}
+		colsToPivot = new LinkedHashMap<String, Comparable>();
+		colsNotToPivot = new ArrayList<String>();
+		
+		String pivotColsStr = m.group(1);
+		String[] pivotCols = pivotColsStr.split(",");
+		for(String s: pivotCols) {
+			colsToPivot.put(s.trim(), null);
+		}
+		
+		String nonPivotColsStr = m.group(2); 
+		String[] nonPivotCols = nonPivotColsStr.split(",");
+		for(String s: nonPivotCols) {
+			colsNotToPivot.add(s.trim());
+		}
+	}
+	
+}

File src_pivot/tbrugz/sqldump/pivot/PivotStatement.java

+package tbrugz.sqldump.pivot;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Statement;
+
+import tbrugz.sqldump.resultset.pivot.PivotResultSet;
+
+/**
+ * Possible sql-pivot syntaxes:
+ * <code>select col1, col2, col3, col4 m1, m2 from (...) /-* pivot col3 asc, col4 desc measures m1, m2 *-/</code>
+ * <code>select col1, col2, col3, col4 m1, m2 from (...) /-* pivot col3 asc, col4 desc nonpivot col1, col2 *-/</code>
+ */
+public class PivotStatement<S extends Statement> implements Statement {
+	
+	final S statement;
+	
+	public PivotStatement(S statement) {
+		this.statement = statement;
+	}
+
+	//XXX
+	public ResultSet executeQuery(String sql) throws SQLException {
+		PivotQueryParser parser = new PivotQueryParser(sql);
+		if(parser.colsToPivot!=null) {
+			return new PivotResultSet(statement.executeQuery(sql), parser.colsNotToPivot, parser.colsToPivot, true);
+		}
+		return statement.executeQuery(sql);
+	}
+
+	public <T> T unwrap(Class<T> iface) throws SQLException {
+		return statement.unwrap(iface);
+	}
+
+	public int executeUpdate(String sql) throws SQLException {
+		return statement.executeUpdate(sql);
+	}
+
+	public boolean isWrapperFor(Class<?> iface) throws SQLException {
+		return statement.isWrapperFor(iface);
+	}
+
+	public void close() throws SQLException {
+		statement.close();
+	}
+
+	public int getMaxFieldSize() throws SQLException {
+		return statement.getMaxFieldSize();
+	}
+
+	public void setMaxFieldSize(int max) throws SQLException {
+		statement.setMaxFieldSize(max);
+	}
+
+	public int getMaxRows() throws SQLException {
+		return statement.getMaxRows();
+	}
+
+	public void setMaxRows(int max) throws SQLException {
+		statement.setMaxRows(max);
+	}
+
+	public void setEscapeProcessing(boolean enable) throws SQLException {
+		statement.setEscapeProcessing(enable);
+	}
+
+	public int getQueryTimeout() throws SQLException {
+		return statement.getQueryTimeout();
+	}
+
+	public void setQueryTimeout(int seconds) throws SQLException {
+		statement.setQueryTimeout(seconds);
+	}
+
+	public void cancel() throws SQLException {
+		statement.cancel();
+	}
+
+	public SQLWarning getWarnings() throws SQLException {
+		return statement.getWarnings();
+	}
+
+	public void clearWarnings() throws SQLException {
+		statement.clearWarnings();
+	}
+
+	public void setCursorName(String name) throws SQLException {
+		statement.setCursorName(name);
+	}
+
+	public boolean execute(String sql) throws SQLException {
+		return statement.execute(sql);
+	}
+
+	//TODO ??
+	public ResultSet getResultSet() throws SQLException {
+		return statement.getResultSet();
+	}
+
+	public int getUpdateCount() throws SQLException {
+		return statement.getUpdateCount();
+	}
+
+	public boolean getMoreResults() throws SQLException {
+		return statement.getMoreResults();
+	}
+
+	public void setFetchDirection(int direction) throws SQLException {
+		statement.setFetchDirection(direction);
+	}
+
+	public int getFetchDirection() throws SQLException {
+		return statement.getFetchDirection();
+	}
+
+	public void setFetchSize(int rows) throws SQLException {
+		statement.setFetchSize(rows);
+	}
+
+	public int getFetchSize() throws SQLException {
+		return statement.getFetchSize();
+	}
+
+	public int getResultSetConcurrency() throws SQLException {
+		return statement.getResultSetConcurrency();
+	}
+
+	public int getResultSetType() throws SQLException {
+		return statement.getResultSetType();
+	}
+
+	public void addBatch(String sql) throws SQLException {
+		statement.addBatch(sql);
+	}
+
+	public void clearBatch() throws SQLException {
+		statement.clearBatch();
+	}
+
+	public int[] executeBatch() throws SQLException {
+		return statement.executeBatch();
+	}
+
+	public Connection getConnection() throws SQLException {
+		return statement.getConnection();
+	}
+
+	public boolean getMoreResults(int current) throws SQLException {
+		return statement.getMoreResults(current);
+	}
+
+	public ResultSet getGeneratedKeys() throws SQLException {
+		return statement.getGeneratedKeys();
+	}
+
+	public int executeUpdate(String sql, int autoGeneratedKeys)
+			throws SQLException {
+		return statement.executeUpdate(sql, autoGeneratedKeys);
+	}
+
+	public int executeUpdate(String sql, int[] columnIndexes)
+			throws SQLException {
+		return statement.executeUpdate(sql, columnIndexes);
+	}
+
+	public int executeUpdate(String sql, String[] columnNames)
+			throws SQLException {
+		return statement.executeUpdate(sql, columnNames);
+	}
+
+	public boolean execute(String sql, int autoGeneratedKeys)
+			throws SQLException {
+		return statement.execute(sql, autoGeneratedKeys);
+	}
+
+	public boolean execute(String sql, int[] columnIndexes) throws SQLException {
+		return statement.execute(sql, columnIndexes);
+	}
+
+	public boolean execute(String sql, String[] columnNames)
+			throws SQLException {
+		return statement.execute(sql, columnNames);
+	}
+
+	public int getResultSetHoldability() throws SQLException {
+		return statement.getResultSetHoldability();
+	}
+
+	public boolean isClosed() throws SQLException {
+		return statement.isClosed();
+	}
+
+	public void setPoolable(boolean poolable) throws SQLException {
+		statement.setPoolable(poolable);
+	}
+
+	public boolean isPoolable() throws SQLException {
+		return statement.isPoolable();
+	}
+
+}

File src_pivot/tbrugz/sqldump/pivot/SQLPivotDriver.java

+package tbrugz.sqldump.pivot;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.DriverPropertyInfo;
+import java.sql.SQLException;
+import java.util.Properties;
+
+public class SQLPivotDriver implements java.sql.Driver {
+	
+	static final String SQLPIVOT_DRIVER_PREFIX = "jdbc:sqlpivot:";
+	
+	static final SQLPivotDriver instance = new SQLPivotDriver();
+	
+	static {
+		try {
+			DriverManager.registerDriver(instance);
+		} catch (SQLException e) {
+			throw new ExceptionInInitializerError(e);
+		}
+	}
+
+	@Override
+	public Connection connect(String url, Properties info) throws SQLException {
+		if(!acceptsURL(url)) {
+			throw new RuntimeException("url '"+url+"' does not match required prefix: "+SQLPIVOT_DRIVER_PREFIX);
+		}
+		String innerUrl = "jdbc:"+url.substring(SQLPIVOT_DRIVER_PREFIX.length());
+		Connection conn = DriverManager.getConnection(innerUrl, info);
+		
+		return new PivotConnection(conn);
+	}
+
+	@Override
+	public boolean acceptsURL(String url) throws SQLException {
+		return url.startsWith(SQLPIVOT_DRIVER_PREFIX);
+	}
+
+	@Override
+	public DriverPropertyInfo[] getPropertyInfo(String url, Properties info)
+			throws SQLException {
+		return null;
+	}
+
+	@Override
+	public int getMajorVersion() {
+		return 1;
+	}
+
+	@Override
+	public int getMinorVersion() {
+		return 0;
+	}
+
+	@Override
+	public boolean jdbcCompliant() {
+		return false;
+	}
+
+}