From 5a9ad3abfceb141c5d44034f1d582706de32c8f9 Mon Sep 17 00:00:00 2001 From: Jeff Wasty Date: Wed, 15 Jan 2025 16:28:08 -0800 Subject: [PATCH] Update --- .../wrapper/CallableStatementWrapper.java | 1118 +++++++++++++++++ .../crd/data/wrapper/ConnectionWrapper.java | 327 +++++ .../data/wrapper/DatabaseMetaDataWrapper.java | 940 ++++++++++++++ .../wrapper/PreparedStatementWrapper.java | 552 ++++++++ .../wrapper/ResultSetMetaDataWrapper.java | 152 +++ .../crd/data/wrapper/ResultSetWrapper.java | 1013 +++++++++++++++ .../crd/data/wrapper/StatementWrapper.java | 259 ++++ .../jtds/CrdJtdsCallableStatement.java | 75 ++ .../data/wrapper/jtds/CrdJtdsConnection.java | 100 ++ .../wrapper/jtds/CrdJtdsDatabaseMetaData.java | 127 ++ .../jtds/CrdJtdsPreparedStatement.java | 80 ++ .../data/wrapper/jtds/CrdJtdsResultSet.java | 94 ++ .../jtds/CrdJtdsResultSetMetaData.java | 96 ++ .../data/wrapper/jtds/CrdJtdsStatement.java | 52 + .../data/wrapper/jtds/TimestampFormat.java | 35 + .../sqlserver/jdbc/issues/Driver.java | 8 +- .../sqlserver/jdbc/issues/GH2514.java | 13 + .../sqlserver/jdbc/issues/GH2518.java | 28 + .../sqlserver/jdbc/issues/GH2534.java | 37 + .../sqlserver/jdbc/issues/perf/Main.java | 145 +++ .../issues/perf/PerfTablePerformanceTest.java | 106 ++ .../jdbc/issues/perf/PerformanceTest.java | 32 + .../jdbc/issues/perf/PreparePerfTables.java | 148 +++ 23 files changed, 5531 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/crd/data/wrapper/CallableStatementWrapper.java create mode 100644 src/main/java/com/crd/data/wrapper/ConnectionWrapper.java create mode 100644 src/main/java/com/crd/data/wrapper/DatabaseMetaDataWrapper.java create mode 100644 src/main/java/com/crd/data/wrapper/PreparedStatementWrapper.java create mode 100644 src/main/java/com/crd/data/wrapper/ResultSetMetaDataWrapper.java create mode 100644 src/main/java/com/crd/data/wrapper/ResultSetWrapper.java create mode 100644 src/main/java/com/crd/data/wrapper/StatementWrapper.java create mode 100644 src/main/java/com/crd/data/wrapper/jtds/CrdJtdsCallableStatement.java create mode 100644 src/main/java/com/crd/data/wrapper/jtds/CrdJtdsConnection.java create mode 100644 src/main/java/com/crd/data/wrapper/jtds/CrdJtdsDatabaseMetaData.java create mode 100644 src/main/java/com/crd/data/wrapper/jtds/CrdJtdsPreparedStatement.java create mode 100644 src/main/java/com/crd/data/wrapper/jtds/CrdJtdsResultSet.java create mode 100644 src/main/java/com/crd/data/wrapper/jtds/CrdJtdsResultSetMetaData.java create mode 100644 src/main/java/com/crd/data/wrapper/jtds/CrdJtdsStatement.java create mode 100644 src/main/java/com/crd/data/wrapper/jtds/TimestampFormat.java create mode 100644 src/test/java/com/microsoft/sqlserver/jdbc/issues/GH2514.java create mode 100644 src/test/java/com/microsoft/sqlserver/jdbc/issues/GH2518.java create mode 100644 src/test/java/com/microsoft/sqlserver/jdbc/issues/GH2534.java create mode 100644 src/test/java/com/microsoft/sqlserver/jdbc/issues/perf/Main.java create mode 100644 src/test/java/com/microsoft/sqlserver/jdbc/issues/perf/PerfTablePerformanceTest.java create mode 100644 src/test/java/com/microsoft/sqlserver/jdbc/issues/perf/PerformanceTest.java create mode 100644 src/test/java/com/microsoft/sqlserver/jdbc/issues/perf/PreparePerfTables.java diff --git a/src/main/java/com/crd/data/wrapper/CallableStatementWrapper.java b/src/main/java/com/crd/data/wrapper/CallableStatementWrapper.java new file mode 100644 index 000000000..d4735ba59 --- /dev/null +++ b/src/main/java/com/crd/data/wrapper/CallableStatementWrapper.java @@ -0,0 +1,1118 @@ +/* Copyright (c) 2015 + * by Charles River Development, Inc., Burlington, MA + * + * This software is furnished under a license and may be used only in + * accordance with the terms of such license. This software may not be + * provided or otherwise made available to any other party. No title to + * nor ownership of the software is hereby transferred. + * + * This software is the intellectual property of Charles River Development, Inc., + * and is protected by the copyright laws of the United States of America. + * All rights reserved internationally. + * + */ + +package com.crd.data.wrapper; + +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.CallableStatement; +import java.sql.Clob; +import java.sql.Connection; +import java.sql.Date; +import java.sql.NClob; +import java.sql.ParameterMetaData; +import java.sql.Ref; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.RowId; +import java.sql.SQLException; +import java.sql.SQLWarning; +import java.sql.SQLXML; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.Calendar; +import java.util.Map; + +/** + * Default wrapper around the CallableStatement + * @author yshao + * + */ +public class CallableStatementWrapper implements CallableStatement { + + private final CallableStatement cStatement; + + public CallableStatementWrapper(CallableStatement pStatement) { + this.cStatement = pStatement; + } + + @Override + public T unwrap(Class iface) throws SQLException { + if (isWrapperFor(iface)) { + return (T)cStatement; + } + throw new SQLException("This is not a wrapper of a CallableStatement"); + } + + @Override + public boolean isWrapperFor(Class iface) throws SQLException { + return cStatement.isWrapperFor(iface); + } + + @Override + public ResultSet executeQuery(String sql) throws SQLException { + return cStatement.executeQuery(sql); + } + + @Override + public int executeUpdate(String sql) throws SQLException { + return cStatement.executeUpdate(sql); + } + + @Override + public void close() throws SQLException { + cStatement.close(); + } + + @Override + public int getMaxFieldSize() throws SQLException { + return cStatement.getMaxFieldSize(); + } + + @Override + public void setMaxFieldSize(int max) throws SQLException { + cStatement.setMaxFieldSize(max); + } + + @Override + public int getMaxRows() throws SQLException { + return cStatement.getMaxRows(); + } + + @Override + public void setMaxRows(int max) throws SQLException { + cStatement.setMaxRows(max); + } + + @Override + public void setEscapeProcessing(boolean enable) throws SQLException { + cStatement.setEscapeProcessing(enable); + } + + @Override + public int getQueryTimeout() throws SQLException { + return cStatement.getQueryTimeout(); + } + + @Override + public void setQueryTimeout(int seconds) throws SQLException { + cStatement.setQueryTimeout(seconds); + } + + @Override + public void cancel() throws SQLException { + cStatement.cancel(); + } + + @Override + public SQLWarning getWarnings() throws SQLException { + return cStatement.getWarnings(); + } + + @Override + public void clearWarnings() throws SQLException { + cStatement.clearWarnings(); + } + + @Override + public void setCursorName(String name) throws SQLException { + cStatement.setCursorName(name); + } + + @Override + public boolean execute(String sql) throws SQLException { + return cStatement.execute(sql); + } + + @Override + public ResultSet getResultSet() throws SQLException { + return cStatement.getResultSet(); + } + + @Override + public int getUpdateCount() throws SQLException { + return cStatement.getUpdateCount(); + } + + @Override + public boolean getMoreResults() throws SQLException { + return cStatement.getMoreResults(); + } + + @Override + public void setFetchDirection(int direction) throws SQLException { + cStatement.setFetchDirection(direction); + } + + @Override + public int getFetchDirection() throws SQLException { + return cStatement.getFetchDirection(); + } + + @Override + public void setFetchSize(int rows) throws SQLException { + cStatement.setFetchSize(rows); + } + + @Override + public int getFetchSize() throws SQLException { + return cStatement.getFetchSize(); + } + + @Override + public int getResultSetConcurrency() throws SQLException { + return cStatement.getResultSetConcurrency(); + } + + @Override + public int getResultSetType() throws SQLException { + return cStatement.getResultSetType(); + } + + @Override + public void addBatch(String sql) throws SQLException { + cStatement.addBatch(sql); + } + + @Override + public void clearBatch() throws SQLException { + cStatement.clearBatch(); + } + + @Override + public int[] executeBatch() throws SQLException { + return cStatement.executeBatch(); + } + + @Override + public Connection getConnection() throws SQLException { + return cStatement.getConnection(); + } + + @Override + public boolean getMoreResults(int current) throws SQLException { + return cStatement.getMoreResults(current); + } + + @Override + public ResultSet getGeneratedKeys() throws SQLException { + return cStatement.getGeneratedKeys(); + } + + @Override + public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { + return cStatement.executeUpdate(sql, autoGeneratedKeys); + } + + @Override + public int executeUpdate(String sql, int[] columnIndexes) throws SQLException { + return cStatement.executeUpdate(sql, columnIndexes); + } + + @Override + public int executeUpdate(String sql, String[] columnNames) throws SQLException { + return cStatement.executeUpdate(sql, columnNames); + } + + @Override + public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { + return cStatement.execute(sql, autoGeneratedKeys); + } + + @Override + public boolean execute(String sql, int[] columnIndexes) throws SQLException { + return cStatement.execute(sql, columnIndexes); + } + + @Override + public boolean execute(String sql, String[] columnNames) throws SQLException { + return cStatement.execute(sql, columnNames); + } + + @Override + public int getResultSetHoldability() throws SQLException { + return cStatement.getResultSetHoldability(); + } + + @Override + public boolean isClosed() throws SQLException { + return cStatement.isClosed(); + } + + @Override + public void setPoolable(boolean poolable) throws SQLException { + cStatement.setPoolable(poolable); + } + + @Override + public boolean isPoolable() throws SQLException { + return cStatement.isPoolable(); + } + + @Override + public void closeOnCompletion() throws SQLException { + cStatement.closeOnCompletion(); + } + + @Override + public boolean isCloseOnCompletion() throws SQLException { + return cStatement.isCloseOnCompletion(); + } + + @Override + public ResultSet executeQuery() throws SQLException { + return cStatement.executeQuery(); + } + + @Override + public int executeUpdate() throws SQLException { + return cStatement.executeUpdate(); + } + + @Override + public void setNull(int parameterIndex, int sqlType) throws SQLException { + cStatement.setNull(parameterIndex, sqlType); + } + + @Override + public void setBoolean(int parameterIndex, boolean x) throws SQLException { + cStatement.setBoolean(parameterIndex, x); + } + + @Override + public void setByte(int parameterIndex, byte x) throws SQLException { + cStatement.setByte(parameterIndex, x); + } + + @Override + public void setShort(int parameterIndex, short x) throws SQLException { + cStatement.setShort(parameterIndex, x); + } + + @Override + public void setInt(int parameterIndex, int x) throws SQLException { + cStatement.setInt(parameterIndex, x); + } + + @Override + public void setLong(int parameterIndex, long x) throws SQLException { + cStatement.setLong(parameterIndex, x); + } + + @Override + public void setFloat(int parameterIndex, float x) throws SQLException { + cStatement.setFloat(parameterIndex, x); + } + + @Override + public void setDouble(int parameterIndex, double x) throws SQLException { + cStatement.setDouble(parameterIndex, x); + } + + @Override + public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException { + cStatement.setBigDecimal(parameterIndex, x); + } + + @Override + public void setString(int parameterIndex, String x) throws SQLException { + cStatement.setString(parameterIndex, x); + } + + @Override + public void setBytes(int parameterIndex, byte[] x) throws SQLException { + cStatement.setBytes(parameterIndex, x); + } + + @Override + public void setDate(int parameterIndex, Date x) throws SQLException { + cStatement.setDate(parameterIndex, x); + } + + @Override + public void setTime(int parameterIndex, Time x) throws SQLException { + cStatement.setTime(parameterIndex, x); + } + + @Override + public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException { + cStatement.setTimestamp(parameterIndex, x); + } + + @Override + public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException { + cStatement.setAsciiStream(parameterIndex, x, length); + } + + @Override + @Deprecated + public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException { + cStatement.setUnicodeStream(parameterIndex, x, length); + } + + @Override + public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException { + cStatement.setBinaryStream(parameterIndex, x, length); + } + + @Override + public void clearParameters() throws SQLException { + cStatement.clearParameters(); + } + + @Override + public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException { + cStatement.setObject(parameterIndex, x, targetSqlType); + } + + @Override + public void setObject(int parameterIndex, Object x) throws SQLException { + cStatement.setObject(parameterIndex, x); + } + + @Override + public boolean execute() throws SQLException { + return cStatement.execute(); + } + + @Override + public void addBatch() throws SQLException { + cStatement.addBatch(); + } + + @Override + public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException { + cStatement.setCharacterStream(parameterIndex, reader, length); + } + + @Override + public void setRef(int parameterIndex, Ref x) throws SQLException { + cStatement.setRef(parameterIndex, x); + } + + @Override + public void setBlob(int parameterIndex, Blob x) throws SQLException { + cStatement.setBlob(parameterIndex, x); + } + + @Override + public void setClob(int parameterIndex, Clob x) throws SQLException { + cStatement.setClob(parameterIndex, x); + } + + @Override + public void setArray(int parameterIndex, Array x) throws SQLException { + cStatement.setArray(parameterIndex, x); + } + + @Override + public ResultSetMetaData getMetaData() throws SQLException { + return cStatement.getMetaData(); + } + + @Override + public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException { + cStatement.setDate(parameterIndex, x, cal); + } + + @Override + public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException { + cStatement.setTime(parameterIndex, x, cal); + } + + @Override + public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException { + cStatement.setTimestamp(parameterIndex, x, cal); + } + + @Override + public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException { + cStatement.setNull(parameterIndex, sqlType, typeName); + } + + @Override + public void setURL(int parameterIndex, URL x) throws SQLException { + cStatement.setURL(parameterIndex, x); + } + + @Override + public ParameterMetaData getParameterMetaData() throws SQLException { + return cStatement.getParameterMetaData(); + } + + @Override + public void setRowId(int parameterIndex, RowId x) throws SQLException { + cStatement.setRowId(parameterIndex, x); + } + + @Override + public void setNString(int parameterIndex, String value) throws SQLException { + cStatement.setNString(parameterIndex, value); + } + + @Override + public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException { + cStatement.setNCharacterStream(parameterIndex, value, length); + } + + @Override + public void setNClob(int parameterIndex, NClob value) throws SQLException { + cStatement.setNClob(parameterIndex, value); + } + + @Override + public void setClob(int parameterIndex, Reader reader, long length) throws SQLException { + cStatement.setClob(parameterIndex, reader, length); + } + + @Override + public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException { + cStatement.setBlob(parameterIndex, inputStream, length); + } + + @Override + public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException { + cStatement.setNClob(parameterIndex, reader, length); + } + + @Override + public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException { + cStatement.setSQLXML(parameterIndex, xmlObject); + } + + @Override + public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException { + cStatement.setObject(parameterIndex, x, targetSqlType, scaleOrLength); + } + + @Override + public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException { + cStatement.setAsciiStream(parameterIndex, x, length); + } + + @Override + public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException { + cStatement.setBinaryStream(parameterIndex, x, length); + } + + @Override + public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException { + cStatement.setCharacterStream(parameterIndex, reader, length); + } + + @Override + public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException { + cStatement.setAsciiStream(parameterIndex, x); + } + + @Override + public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException { + cStatement.setBinaryStream(parameterIndex, x); + } + + @Override + public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException { + cStatement.setCharacterStream(parameterIndex, reader); + } + + @Override + public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException { + cStatement.setNCharacterStream(parameterIndex, value); + } + + @Override + public void setClob(int parameterIndex, Reader reader) throws SQLException { + cStatement.setClob(parameterIndex, reader); + } + + @Override + public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException { + cStatement.setBlob(parameterIndex, inputStream); + } + + @Override + public void setNClob(int parameterIndex, Reader reader) throws SQLException { + cStatement.setNClob(parameterIndex, reader); + } + + @Override + public void registerOutParameter(int parameterIndex, int sqlType) throws SQLException { + cStatement.registerOutParameter(parameterIndex, sqlType); + } + + @Override + public void registerOutParameter(int parameterIndex, int sqlType, int scale) throws SQLException { + cStatement.registerOutParameter(parameterIndex, sqlType, scale); + } + + @Override + public boolean wasNull() throws SQLException { + return cStatement.wasNull(); + } + + @Override + public String getString(int parameterIndex) throws SQLException { + return cStatement.getString(parameterIndex); + } + + @Override + public boolean getBoolean(int parameterIndex) throws SQLException { + return cStatement.getBoolean(parameterIndex); + } + + @Override + public byte getByte(int parameterIndex) throws SQLException { + return cStatement.getByte(parameterIndex); + } + + @Override + public short getShort(int parameterIndex) throws SQLException { + return cStatement.getShort(parameterIndex); + } + + @Override + public int getInt(int parameterIndex) throws SQLException { + return cStatement.getInt(parameterIndex); + } + + @Override + public long getLong(int parameterIndex) throws SQLException { + return cStatement.getLong(parameterIndex); + } + + @Override + public float getFloat(int parameterIndex) throws SQLException { + return cStatement.getFloat(parameterIndex); + } + + @Override + public double getDouble(int parameterIndex) throws SQLException { + return cStatement.getDouble(parameterIndex); + } + + @Override + @Deprecated + public BigDecimal getBigDecimal(int parameterIndex, int scale) throws SQLException { + return cStatement.getBigDecimal(parameterIndex, scale); + } + + @Override + public byte[] getBytes(int parameterIndex) throws SQLException { + return cStatement.getBytes(parameterIndex); + } + + @Override + public Date getDate(int parameterIndex) throws SQLException { + return cStatement.getDate(parameterIndex); + } + + @Override + public Time getTime(int parameterIndex) throws SQLException { + return cStatement.getTime(parameterIndex); + } + + @Override + public Timestamp getTimestamp(int parameterIndex) throws SQLException { + return cStatement.getTimestamp(parameterIndex); + } + + @Override + public Object getObject(int parameterIndex) throws SQLException { + return cStatement.getObject(parameterIndex); + } + + @Override + public BigDecimal getBigDecimal(int parameterIndex) throws SQLException { + return cStatement.getBigDecimal(parameterIndex); + } + + @Override + public Object getObject(int parameterIndex, Map> map) throws SQLException { + return cStatement.getObject(parameterIndex, map); + } + + @Override + public Ref getRef(int parameterIndex) throws SQLException { + return cStatement.getRef(parameterIndex); + } + + @Override + public Blob getBlob(int parameterIndex) throws SQLException { + return cStatement.getBlob(parameterIndex); + } + + @Override + public Clob getClob(int parameterIndex) throws SQLException { + return cStatement.getClob(parameterIndex); + } + + @Override + public Array getArray(int parameterIndex) throws SQLException { + return cStatement.getArray(parameterIndex); + } + + @Override + public Date getDate(int parameterIndex, Calendar cal) throws SQLException { + return cStatement.getDate(parameterIndex, cal); + } + + @Override + public Time getTime(int parameterIndex, Calendar cal) throws SQLException { + return cStatement.getTime(parameterIndex, cal); + } + + @Override + public Timestamp getTimestamp(int parameterIndex, Calendar cal) throws SQLException { + return cStatement.getTimestamp(parameterIndex, cal); + } + + @Override + public void registerOutParameter(int parameterIndex, int sqlType, String typeName) throws SQLException { + cStatement.registerOutParameter(parameterIndex, sqlType, typeName); + } + + @Override + public void registerOutParameter(String parameterName, int sqlType) throws SQLException { + cStatement.registerOutParameter(parameterName, sqlType); + } + + @Override + public void registerOutParameter(String parameterName, int sqlType, int scale) throws SQLException { + cStatement.registerOutParameter(parameterName, sqlType, scale); + } + + @Override + public void registerOutParameter(String parameterName, int sqlType, String typeName) throws SQLException { + cStatement.registerOutParameter(parameterName, sqlType, typeName); + } + + @Override + public URL getURL(int parameterIndex) throws SQLException { + return cStatement.getURL(parameterIndex); + } + + @Override + public void setURL(String parameterName, URL val) throws SQLException { + cStatement.setURL(parameterName, val); + } + + @Override + public void setNull(String parameterName, int sqlType) throws SQLException { + cStatement.setNull(parameterName, sqlType); + } + + @Override + public void setBoolean(String parameterName, boolean x) throws SQLException { + cStatement.setBoolean(parameterName, x); + } + + @Override + public void setByte(String parameterName, byte x) throws SQLException { + cStatement.setByte(parameterName, x); + } + + @Override + public void setShort(String parameterName, short x) throws SQLException { + cStatement.setShort(parameterName, x); + } + + @Override + public void setInt(String parameterName, int x) throws SQLException { + cStatement.setInt(parameterName, x); + } + + @Override + public void setLong(String parameterName, long x) throws SQLException { + cStatement.setLong(parameterName, x); + } + + @Override + public void setFloat(String parameterName, float x) throws SQLException { + cStatement.setFloat(parameterName, x); + } + + @Override + public void setDouble(String parameterName, double x) throws SQLException { + cStatement.setDouble(parameterName, x); + } + + @Override + public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException { + cStatement.setBigDecimal(parameterName, x); + } + + @Override + public void setString(String parameterName, String x) throws SQLException { + cStatement.setString(parameterName, x); + } + + @Override + public void setBytes(String parameterName, byte[] x) throws SQLException { + cStatement.setBytes(parameterName, x); + } + + @Override + public void setDate(String parameterName, Date x) throws SQLException { + cStatement.setDate(parameterName, x); + } + + @Override + public void setTime(String parameterName, Time x) throws SQLException { + cStatement.setTime(parameterName, x); + } + + @Override + public void setTimestamp(String parameterName, Timestamp x) throws SQLException { + cStatement.setTimestamp(parameterName, x); + } + + @Override + public void setAsciiStream(String parameterName, InputStream x, int length) throws SQLException { + cStatement.setAsciiStream(parameterName, x, length); + } + + @Override + public void setBinaryStream(String parameterName, InputStream x, int length) throws SQLException { + cStatement.setBinaryStream(parameterName, x, length); + } + + @Override + public void setObject(String parameterName, Object x, int targetSqlType, int scale) throws SQLException { + cStatement.setObject(parameterName, x, targetSqlType, scale); + } + + @Override + public void setObject(String parameterName, Object x, int targetSqlType) throws SQLException { + cStatement.setObject(parameterName, x, targetSqlType); + } + + @Override + public void setObject(String parameterName, Object x) throws SQLException { + cStatement.setObject(parameterName, x); + } + + @Override + public void setCharacterStream(String parameterName, Reader reader, int length) throws SQLException { + cStatement.setCharacterStream(parameterName, reader, length); + } + + @Override + public void setDate(String parameterName, Date x, Calendar cal) throws SQLException { + cStatement.setDate(parameterName, x, cal); + } + + @Override + public void setTime(String parameterName, Time x, Calendar cal) throws SQLException { + cStatement.setTime(parameterName, x, cal); + } + + @Override + public void setTimestamp(String parameterName, Timestamp x, Calendar cal) throws SQLException { + cStatement.setTimestamp(parameterName, x, cal); + } + + @Override + public void setNull(String parameterName, int sqlType, String typeName) throws SQLException { + cStatement.setNull(parameterName, sqlType, typeName); + } + + @Override + public String getString(String parameterName) throws SQLException { + return cStatement.getString(parameterName); + } + + @Override + public boolean getBoolean(String parameterName) throws SQLException { + return cStatement.getBoolean(parameterName); + } + + @Override + public byte getByte(String parameterName) throws SQLException { + return cStatement.getByte(parameterName); + } + + @Override + public short getShort(String parameterName) throws SQLException { + return cStatement.getShort(parameterName); + } + + @Override + public int getInt(String parameterName) throws SQLException { + return cStatement.getInt(parameterName); + } + + @Override + public long getLong(String parameterName) throws SQLException { + return cStatement.getLong(parameterName); + } + + @Override + public float getFloat(String parameterName) throws SQLException { + return cStatement.getFloat(parameterName); + } + + @Override + public double getDouble(String parameterName) throws SQLException { + return cStatement.getDouble(parameterName); + } + + @Override + public byte[] getBytes(String parameterName) throws SQLException { + return cStatement.getBytes(parameterName); + } + + @Override + public Date getDate(String parameterName) throws SQLException { + return cStatement.getDate(parameterName); + } + + @Override + public Time getTime(String parameterName) throws SQLException { + return cStatement.getTime(parameterName); + } + + @Override + public Timestamp getTimestamp(String parameterName) throws SQLException { + return cStatement.getTimestamp(parameterName); + } + + @Override + public Object getObject(String parameterName) throws SQLException { + return cStatement.getObject(parameterName); + } + + @Override + public BigDecimal getBigDecimal(String parameterName) throws SQLException { + return cStatement.getBigDecimal(parameterName); + } + + @Override + public Object getObject(String parameterName, Map> map) throws SQLException { + return cStatement.getObject(parameterName, map); + } + + @Override + public Ref getRef(String parameterName) throws SQLException { + return cStatement.getRef(parameterName); + } + + @Override + public Blob getBlob(String parameterName) throws SQLException { + return cStatement.getBlob(parameterName); + } + + @Override + public Clob getClob(String parameterName) throws SQLException { + return cStatement.getClob(parameterName); + } + + @Override + public Array getArray(String parameterName) throws SQLException { + return cStatement.getArray(parameterName); + } + + @Override + public Date getDate(String parameterName, Calendar cal) throws SQLException { + return cStatement.getDate(parameterName, cal); + } + + @Override + public Time getTime(String parameterName, Calendar cal) throws SQLException { + return cStatement.getTime(parameterName, cal); + } + + @Override + public Timestamp getTimestamp(String parameterName, Calendar cal) throws SQLException { + return cStatement.getTimestamp(parameterName, cal); + } + + @Override + public URL getURL(String parameterName) throws SQLException { + return cStatement.getURL(parameterName); + } + + @Override + public RowId getRowId(int parameterIndex) throws SQLException { + return cStatement.getRowId(parameterIndex); + } + + @Override + public RowId getRowId(String parameterName) throws SQLException { + return cStatement.getRowId(parameterName); + } + + @Override + public void setRowId(String parameterName, RowId x) throws SQLException { + cStatement.setRowId(parameterName, x); + } + + @Override + public void setNString(String parameterName, String value) throws SQLException { + cStatement.setNString(parameterName, value); + } + + @Override + public void setNCharacterStream(String parameterName, Reader value, long length) throws SQLException { + cStatement.setNCharacterStream(parameterName, value, length); + } + + @Override + public void setNClob(String parameterName, NClob value) throws SQLException { + cStatement.setNClob(parameterName, value); + } + + @Override + public void setClob(String parameterName, Reader reader, long length) throws SQLException { + cStatement.setClob(parameterName, reader, length); + } + + @Override + public void setBlob(String parameterName, InputStream inputStream, long length) throws SQLException { + cStatement.setBlob(parameterName, inputStream, length); + } + + @Override + public void setNClob(String parameterName, Reader reader, long length) throws SQLException { + cStatement.setNClob(parameterName, reader, length); + } + + @Override + public NClob getNClob(int parameterIndex) throws SQLException { + return cStatement.getNClob(parameterIndex); + } + + @Override + public NClob getNClob(String parameterName) throws SQLException { + return cStatement.getNClob(parameterName); + } + + @Override + public void setSQLXML(String parameterName, SQLXML xmlObject) throws SQLException { + cStatement.setSQLXML(parameterName, xmlObject); + } + + @Override + public SQLXML getSQLXML(int parameterIndex) throws SQLException { + return cStatement.getSQLXML(parameterIndex); + } + + @Override + public SQLXML getSQLXML(String parameterName) throws SQLException { + return cStatement.getSQLXML(parameterName); + } + + @Override + public String getNString(int parameterIndex) throws SQLException { + return cStatement.getNString(parameterIndex); + } + + @Override + public String getNString(String parameterName) throws SQLException { + return cStatement.getNString(parameterName); + } + + @Override + public Reader getNCharacterStream(int parameterIndex) throws SQLException { + return cStatement.getNCharacterStream(parameterIndex); + } + + @Override + public Reader getNCharacterStream(String parameterName) throws SQLException { + return cStatement.getNCharacterStream(parameterName); + } + + @Override + public Reader getCharacterStream(int parameterIndex) throws SQLException { + return cStatement.getCharacterStream(parameterIndex); + } + + @Override + public Reader getCharacterStream(String parameterName) throws SQLException { + return cStatement.getCharacterStream(parameterName); + } + + @Override + public void setBlob(String parameterName, Blob x) throws SQLException { + cStatement.setBlob(parameterName, x); + } + + @Override + public void setClob(String parameterName, Clob x) throws SQLException { + cStatement.setClob(parameterName, x); + } + + @Override + public void setAsciiStream(String parameterName, InputStream x, long length) throws SQLException { + cStatement.setAsciiStream(parameterName, x, length); + } + + @Override + public void setBinaryStream(String parameterName, InputStream x, long length) throws SQLException { + cStatement.setBinaryStream(parameterName, x, length); + } + + @Override + public void setCharacterStream(String parameterName, Reader reader, long length) throws SQLException { + cStatement.setCharacterStream(parameterName, reader, length); + } + + @Override + public void setAsciiStream(String parameterName, InputStream x) throws SQLException { + cStatement.setAsciiStream(parameterName, x); + } + + @Override + public void setBinaryStream(String parameterName, InputStream x) throws SQLException { + cStatement.setBinaryStream(parameterName, x); + } + + @Override + public void setCharacterStream(String parameterName, Reader reader) throws SQLException { + cStatement.setCharacterStream(parameterName, reader); + } + + @Override + public void setNCharacterStream(String parameterName, Reader value) throws SQLException { + cStatement.setNCharacterStream(parameterName, value); + } + + @Override + public void setClob(String parameterName, Reader reader) throws SQLException { + cStatement.setClob(parameterName, reader); + } + + @Override + public void setBlob(String parameterName, InputStream inputStream) throws SQLException { + cStatement.setBlob(parameterName, inputStream); + } + + @Override + public void setNClob(String parameterName, Reader reader) throws SQLException { + cStatement.setNClob(parameterName, reader); + } + + @Override + public T getObject(int parameterIndex, Class type) throws SQLException { + return cStatement.getObject(parameterIndex, type); + } + + @Override + public T getObject(String parameterName, Class type) throws SQLException { + return cStatement.getObject(parameterName, type); + } +} diff --git a/src/main/java/com/crd/data/wrapper/ConnectionWrapper.java b/src/main/java/com/crd/data/wrapper/ConnectionWrapper.java new file mode 100644 index 000000000..a041f16d0 --- /dev/null +++ b/src/main/java/com/crd/data/wrapper/ConnectionWrapper.java @@ -0,0 +1,327 @@ +/* Copyright (c) 2015 + * by Charles River Development, Inc., Burlington, MA + * + * This software is furnished under a license and may be used only in + * accordance with the terms of such license. This software may not be + * provided or otherwise made available to any other party. No title to + * nor ownership of the software is hereby transferred. + * + * This software is the intellectual property of Charles River Development, Inc., + * and is protected by the copyright laws of the United States of America. + * All rights reserved internationally. + * + */ + +package com.crd.data.wrapper; + +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; +import java.util.concurrent.Executor; + +/** + * Default wrapper around the Connection + * @author yshao + * + */ +public class ConnectionWrapper implements Connection { + + private final Connection conn; + + public ConnectionWrapper(Connection conn) { + this.conn = conn; + } + + @Override + public T unwrap(Class iface) throws SQLException { + if (isWrapperFor(iface)) { + return (T)conn; + } + throw new SQLException("This is not a wrapper of a Connection"); + } + + @Override + public boolean isWrapperFor(Class iface) throws SQLException { + return conn.isWrapperFor(iface); + } + + @Override + public Statement createStatement() throws SQLException { + return conn.createStatement(); + } + + @Override + public PreparedStatement prepareStatement(String sql) throws SQLException { + return conn.prepareStatement(sql); + } + + @Override + public CallableStatement prepareCall(String sql) throws SQLException { + return conn.prepareCall(sql); + } + + @Override + public String nativeSQL(String sql) throws SQLException { + return conn.nativeSQL(sql); + } + + @Override + public void setAutoCommit(boolean autoCommit) throws SQLException { + conn.setAutoCommit(autoCommit); + } + + @Override + public boolean getAutoCommit() throws SQLException { + return conn.getAutoCommit(); + } + + @Override + public void commit() throws SQLException { + conn.commit(); + } + + @Override + public void rollback() throws SQLException { + conn.rollback(); + } + + @Override + public void close() throws SQLException { + conn.close(); + } + + @Override + public boolean isClosed() throws SQLException { + return conn.isClosed(); + } + + @Override + public DatabaseMetaData getMetaData() throws SQLException { + return conn.getMetaData(); + } + + @Override + public void setReadOnly(boolean readOnly) throws SQLException { + conn.setReadOnly(readOnly); + } + + @Override + public boolean isReadOnly() throws SQLException { + return conn.isReadOnly(); + } + + @Override + public void setCatalog(String catalog) throws SQLException { + conn.setCatalog(catalog); + } + + @Override + public String getCatalog() throws SQLException { + return conn.getCatalog(); + } + + @Override + public void setTransactionIsolation(int level) throws SQLException { + conn.setTransactionIsolation(level); + } + + @Override + public int getTransactionIsolation() throws SQLException { + return conn.getTransactionIsolation(); + } + + @Override + public SQLWarning getWarnings() throws SQLException { + return conn.getWarnings(); + } + + @Override + public void clearWarnings() throws SQLException { + conn.clearWarnings(); + } + + @Override + public Statement createStatement(int resultSetType, int resultSetConcurrency) + throws SQLException { + return conn.createStatement(resultSetType, resultSetConcurrency); + } + + @Override + public PreparedStatement prepareStatement(String sql, int resultSetType, + int resultSetConcurrency) throws SQLException { + return conn.prepareStatement(sql, resultSetType, resultSetConcurrency); + } + + @Override + public CallableStatement prepareCall(String sql, int resultSetType, + int resultSetConcurrency) throws SQLException { + return conn.prepareCall(sql, resultSetType, resultSetConcurrency); + } + + @Override + public Map> getTypeMap() throws SQLException { + return conn.getTypeMap(); + } + + @Override + public void setTypeMap(Map> map) throws SQLException { + conn.setTypeMap(map); + } + + @Override + public void setHoldability(int holdability) throws SQLException { + conn.setHoldability(holdability); + } + + @Override + public int getHoldability() throws SQLException { + return conn.getHoldability(); + } + + @Override + public Savepoint setSavepoint() throws SQLException { + return conn.setSavepoint(); + } + + @Override + public Savepoint setSavepoint(String name) throws SQLException { + return conn.setSavepoint(name); + } + + @Override + public void rollback(Savepoint savepoint) throws SQLException { + conn.rollback(savepoint); + } + + @Override + public void releaseSavepoint(Savepoint savepoint) throws SQLException { + conn.releaseSavepoint(savepoint); + } + + @Override + public Statement createStatement(int resultSetType, + int resultSetConcurrency, int resultSetHoldability) throws SQLException { + return conn.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability); + } + + @Override + public PreparedStatement prepareStatement(String sql, int resultSetType, + int resultSetConcurrency, int resultSetHoldability) throws SQLException { + return conn.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability); + } + + @Override + public CallableStatement prepareCall(String sql, int resultSetType, + int resultSetConcurrency, int resultSetHoldability) throws SQLException { + return conn.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability); + } + + @Override + public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { + return conn.prepareStatement(sql, autoGeneratedKeys); + } + + @Override + public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException { + return conn.prepareStatement(sql, columnIndexes); + } + + @Override + public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException { + return conn.prepareStatement(sql, columnNames); + } + + @Override + public Clob createClob() throws SQLException { + return conn.createClob(); + } + + @Override + public Blob createBlob() throws SQLException { + return conn.createBlob(); + } + + @Override + public NClob createNClob() throws SQLException { + return conn.createNClob(); + } + + @Override + public SQLXML createSQLXML() throws SQLException { + return conn.createSQLXML(); + } + + @Override + public boolean isValid(int timeout) throws SQLException { + return conn.isValid(timeout); + } + + @Override + public void setClientInfo(String name, String value) throws SQLClientInfoException { + conn.setClientInfo(name, value); + } + + @Override + public void setClientInfo(Properties properties) throws SQLClientInfoException { + conn.setClientInfo(properties); + } + + @Override + public String getClientInfo(String name) throws SQLException { + return conn.getClientInfo(name); + } + + @Override + public Properties getClientInfo() throws SQLException { + return conn.getClientInfo(); + } + + @Override + public Array createArrayOf(String typeName, Object[] elements) throws SQLException { + return conn.createArrayOf(typeName, elements); + } + + @Override + public Struct createStruct(String typeName, Object[] attributes) throws SQLException { + return conn.createStruct(typeName, attributes); + } + + @Override + public void setSchema(String schema) throws SQLException { + conn.setSchema(schema); + } + + @Override + public String getSchema() throws SQLException { + return conn.getSchema(); + } + + @Override + public void abort(Executor executor) throws SQLException { + conn.abort(executor); + } + + @Override + public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException { + conn.setNetworkTimeout(executor, milliseconds); + } + + @Override + public int getNetworkTimeout() throws SQLException { + return conn.getNetworkTimeout(); + } +} diff --git a/src/main/java/com/crd/data/wrapper/DatabaseMetaDataWrapper.java b/src/main/java/com/crd/data/wrapper/DatabaseMetaDataWrapper.java new file mode 100644 index 000000000..ae7a8c035 --- /dev/null +++ b/src/main/java/com/crd/data/wrapper/DatabaseMetaDataWrapper.java @@ -0,0 +1,940 @@ +/* Copyright (c) 2015 + * by Charles River Development, Inc., Burlington, MA + * + * This software is furnished under a license and may be used only in + * accordance with the terms of such license. This software may not be + * provided or otherwise made available to any other party. No title to + * nor ownership of the software is hereby transferred. + * + * This software is the intellectual property of Charles River Development, Inc., + * and is protected by the copyright laws of the United States of America. + * All rights reserved internationally. + * + */ + +package com.crd.data.wrapper; + +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.ResultSet; +import java.sql.RowIdLifetime; +import java.sql.SQLException; + +/** + * Default wrapper around the DatabaseMetaData + * @author yshao + * + */ +public class DatabaseMetaDataWrapper implements DatabaseMetaData { + + private final DatabaseMetaData dbMetaData; + + public DatabaseMetaDataWrapper(DatabaseMetaData dbMetaData) { + this.dbMetaData = dbMetaData; + } + + @Override + public T unwrap(Class iface) throws SQLException { + if (isWrapperFor(iface)) { + return (T)dbMetaData; + } + throw new SQLException("This is not a wrapper of a DatabaseMetaData"); + } + + @Override + public boolean isWrapperFor(Class iface) throws SQLException { + return dbMetaData.isWrapperFor(iface); + } + + @Override + public boolean allProceduresAreCallable() throws SQLException { + return dbMetaData.allProceduresAreCallable(); + } + + @Override + public boolean allTablesAreSelectable() throws SQLException { + return dbMetaData.allTablesAreSelectable(); + } + + @Override + public String getURL() throws SQLException { + return dbMetaData.getURL(); + } + + @Override + public String getUserName() throws SQLException { + return dbMetaData.getUserName(); + } + + @Override + public boolean isReadOnly() throws SQLException { + return dbMetaData.isReadOnly(); + } + + @Override + public boolean nullsAreSortedHigh() throws SQLException { + return dbMetaData.nullsAreSortedHigh(); + } + + @Override + public boolean nullsAreSortedLow() throws SQLException { + return dbMetaData.nullsAreSortedLow(); + } + + @Override + public boolean nullsAreSortedAtStart() throws SQLException { + return dbMetaData.nullsAreSortedAtStart(); + } + + @Override + public boolean nullsAreSortedAtEnd() throws SQLException { + return dbMetaData.nullsAreSortedAtEnd(); + } + + @Override + public String getDatabaseProductName() throws SQLException { + return dbMetaData.getDatabaseProductName(); + } + + @Override + public String getDatabaseProductVersion() throws SQLException { + return dbMetaData.getDatabaseProductVersion(); + } + + @Override + public String getDriverName() throws SQLException { + return dbMetaData.getDriverName(); + } + + @Override + public String getDriverVersion() throws SQLException { + return dbMetaData.getDriverVersion(); + } + + @Override + public int getDriverMajorVersion() { + return dbMetaData.getDriverMajorVersion(); + } + + @Override + public int getDriverMinorVersion() { + return dbMetaData.getDriverMinorVersion(); + } + + @Override + public boolean usesLocalFiles() throws SQLException { + return dbMetaData.usesLocalFiles(); + } + + @Override + public boolean usesLocalFilePerTable() throws SQLException { + return dbMetaData.usesLocalFilePerTable(); + } + + @Override + public boolean supportsMixedCaseIdentifiers() throws SQLException { + return dbMetaData.supportsMixedCaseIdentifiers(); + } + + @Override + public boolean storesUpperCaseIdentifiers() throws SQLException { + return dbMetaData.storesUpperCaseIdentifiers(); + } + + @Override + public boolean storesLowerCaseIdentifiers() throws SQLException { + return dbMetaData.storesLowerCaseIdentifiers(); + } + + @Override + public boolean storesMixedCaseIdentifiers() throws SQLException { + return dbMetaData.storesMixedCaseIdentifiers(); + } + + @Override + public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException { + return dbMetaData.supportsMixedCaseQuotedIdentifiers(); + } + + @Override + public boolean storesUpperCaseQuotedIdentifiers() throws SQLException { + return dbMetaData.storesUpperCaseQuotedIdentifiers(); + } + + @Override + public boolean storesLowerCaseQuotedIdentifiers() throws SQLException { + return dbMetaData.storesLowerCaseQuotedIdentifiers(); + } + + @Override + public boolean storesMixedCaseQuotedIdentifiers() throws SQLException { + return dbMetaData.storesMixedCaseQuotedIdentifiers(); + } + + @Override + public String getIdentifierQuoteString() throws SQLException { + return dbMetaData.getIdentifierQuoteString(); + } + + @Override + public String getSQLKeywords() throws SQLException { + return dbMetaData.getSQLKeywords(); + } + + @Override + public String getNumericFunctions() throws SQLException { + return dbMetaData.getNumericFunctions(); + } + + @Override + public String getStringFunctions() throws SQLException { + return dbMetaData.getStringFunctions(); + } + + @Override + public String getSystemFunctions() throws SQLException { + return dbMetaData.getSystemFunctions(); + } + + @Override + public String getTimeDateFunctions() throws SQLException { + return dbMetaData.getTimeDateFunctions(); + } + + @Override + public String getSearchStringEscape() throws SQLException { + return dbMetaData.getSearchStringEscape(); + } + + @Override + public String getExtraNameCharacters() throws SQLException { + return dbMetaData.getExtraNameCharacters(); + } + + @Override + public boolean supportsAlterTableWithAddColumn() throws SQLException { + return dbMetaData.supportsAlterTableWithAddColumn(); + } + + @Override + public boolean supportsAlterTableWithDropColumn() throws SQLException { + return dbMetaData.supportsAlterTableWithDropColumn(); + } + + @Override + public boolean supportsColumnAliasing() throws SQLException { + return dbMetaData.supportsColumnAliasing(); + } + + @Override + public boolean nullPlusNonNullIsNull() throws SQLException { + return dbMetaData.nullPlusNonNullIsNull(); + } + + @Override + public boolean supportsConvert() throws SQLException { + return dbMetaData.supportsConvert(); + } + + @Override + public boolean supportsConvert(int fromType, int toType) throws SQLException { + return dbMetaData.supportsConvert(fromType, toType); + } + + @Override + public boolean supportsTableCorrelationNames() throws SQLException { + return dbMetaData.supportsTableCorrelationNames(); + } + + @Override + public boolean supportsDifferentTableCorrelationNames() throws SQLException { + return dbMetaData.supportsDifferentTableCorrelationNames(); + } + + @Override + public boolean supportsExpressionsInOrderBy() throws SQLException { + return dbMetaData.supportsExpressionsInOrderBy(); + } + + @Override + public boolean supportsOrderByUnrelated() throws SQLException { + return dbMetaData.supportsOrderByUnrelated(); + } + + @Override + public boolean supportsGroupBy() throws SQLException { + return dbMetaData.supportsGroupBy(); + } + + @Override + public boolean supportsGroupByUnrelated() throws SQLException { + return dbMetaData.supportsGroupByUnrelated(); + } + + @Override + public boolean supportsGroupByBeyondSelect() throws SQLException { + return dbMetaData.supportsGroupByBeyondSelect(); + } + + @Override + public boolean supportsLikeEscapeClause() throws SQLException { + return dbMetaData.supportsLikeEscapeClause(); + } + + @Override + public boolean supportsMultipleResultSets() throws SQLException { + return dbMetaData.supportsMultipleResultSets(); + } + + @Override + public boolean supportsMultipleTransactions() throws SQLException { + return dbMetaData.supportsMultipleTransactions(); + } + + @Override + public boolean supportsNonNullableColumns() throws SQLException { + return dbMetaData.supportsNonNullableColumns(); + } + + @Override + public boolean supportsMinimumSQLGrammar() throws SQLException { + return dbMetaData.supportsMinimumSQLGrammar(); + } + + @Override + public boolean supportsCoreSQLGrammar() throws SQLException { + return dbMetaData.supportsCoreSQLGrammar(); + } + + @Override + public boolean supportsExtendedSQLGrammar() throws SQLException { + return dbMetaData.supportsExtendedSQLGrammar(); + } + + @Override + public boolean supportsANSI92EntryLevelSQL() throws SQLException { + return dbMetaData.supportsANSI92EntryLevelSQL(); + } + + @Override + public boolean supportsANSI92IntermediateSQL() throws SQLException { + return dbMetaData.supportsANSI92IntermediateSQL(); + } + + @Override + public boolean supportsANSI92FullSQL() throws SQLException { + return dbMetaData.supportsANSI92FullSQL(); + } + + @Override + public boolean supportsIntegrityEnhancementFacility() throws SQLException { + return dbMetaData.supportsIntegrityEnhancementFacility(); + } + + @Override + public boolean supportsOuterJoins() throws SQLException { + return dbMetaData.supportsOuterJoins(); + } + + @Override + public boolean supportsFullOuterJoins() throws SQLException { + return dbMetaData.supportsFullOuterJoins(); + } + + @Override + public boolean supportsLimitedOuterJoins() throws SQLException { + return dbMetaData.supportsLimitedOuterJoins(); + } + + @Override + public String getSchemaTerm() throws SQLException { + return dbMetaData.getSchemaTerm(); + } + + @Override + public String getProcedureTerm() throws SQLException { + return dbMetaData.getProcedureTerm(); + } + + @Override + public String getCatalogTerm() throws SQLException { + return dbMetaData.getCatalogTerm(); + } + + @Override + public boolean isCatalogAtStart() throws SQLException { + return dbMetaData.isCatalogAtStart(); + } + + @Override + public String getCatalogSeparator() throws SQLException { + return dbMetaData.getCatalogSeparator(); + } + + @Override + public boolean supportsSchemasInDataManipulation() throws SQLException { + return dbMetaData.supportsSchemasInDataManipulation(); + } + + @Override + public boolean supportsSchemasInProcedureCalls() throws SQLException { + return dbMetaData.supportsSchemasInProcedureCalls(); + } + + @Override + public boolean supportsSchemasInTableDefinitions() throws SQLException { + return dbMetaData.supportsSchemasInTableDefinitions(); + } + + @Override + public boolean supportsSchemasInIndexDefinitions() throws SQLException { + return dbMetaData.supportsSchemasInIndexDefinitions(); + } + + @Override + public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException { + return dbMetaData.supportsSchemasInPrivilegeDefinitions(); + } + + @Override + public boolean supportsCatalogsInDataManipulation() throws SQLException { + return dbMetaData.supportsCatalogsInDataManipulation(); + } + + @Override + public boolean supportsCatalogsInProcedureCalls() throws SQLException { + return dbMetaData.supportsCatalogsInProcedureCalls(); + } + + @Override + public boolean supportsCatalogsInTableDefinitions() throws SQLException { + return dbMetaData.supportsCatalogsInTableDefinitions(); + } + + @Override + public boolean supportsCatalogsInIndexDefinitions() throws SQLException { + return dbMetaData.supportsCatalogsInIndexDefinitions(); + } + + @Override + public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException { + return dbMetaData.supportsCatalogsInPrivilegeDefinitions(); + } + + @Override + public boolean supportsPositionedDelete() throws SQLException { + return dbMetaData.supportsPositionedDelete(); + } + + @Override + public boolean supportsPositionedUpdate() throws SQLException { + return dbMetaData.supportsPositionedUpdate(); + } + + @Override + public boolean supportsSelectForUpdate() throws SQLException { + return dbMetaData.supportsSelectForUpdate(); + } + + @Override + public boolean supportsStoredProcedures() throws SQLException { + return dbMetaData.supportsStoredProcedures(); + } + + @Override + public boolean supportsSubqueriesInComparisons() throws SQLException { + return dbMetaData.supportsSubqueriesInComparisons(); + } + + @Override + public boolean supportsSubqueriesInExists() throws SQLException { + return dbMetaData.supportsSubqueriesInExists(); + } + + @Override + public boolean supportsSubqueriesInIns() throws SQLException { + return dbMetaData.supportsSubqueriesInIns(); + } + + @Override + public boolean supportsSubqueriesInQuantifieds() throws SQLException { + return dbMetaData.supportsSubqueriesInQuantifieds(); + } + + @Override + public boolean supportsCorrelatedSubqueries() throws SQLException { + return dbMetaData.supportsCorrelatedSubqueries(); + } + + @Override + public boolean supportsUnion() throws SQLException { + return dbMetaData.supportsUnion(); + } + + @Override + public boolean supportsUnionAll() throws SQLException { + return dbMetaData.supportsUnionAll(); + } + + @Override + public boolean supportsOpenCursorsAcrossCommit() throws SQLException { + return dbMetaData.supportsOpenCursorsAcrossCommit(); + } + + @Override + public boolean supportsOpenCursorsAcrossRollback() throws SQLException { + return dbMetaData.supportsOpenCursorsAcrossRollback(); + } + + @Override + public boolean supportsOpenStatementsAcrossCommit() throws SQLException { + return dbMetaData.supportsOpenStatementsAcrossCommit(); + } + + @Override + public boolean supportsOpenStatementsAcrossRollback() throws SQLException { + return dbMetaData.supportsOpenStatementsAcrossRollback(); + } + + @Override + public int getMaxBinaryLiteralLength() throws SQLException { + return dbMetaData.getMaxBinaryLiteralLength(); + } + + @Override + public int getMaxCharLiteralLength() throws SQLException { + return dbMetaData.getMaxCharLiteralLength(); + } + + @Override + public int getMaxColumnNameLength() throws SQLException { + return dbMetaData.getMaxColumnNameLength(); + } + + @Override + public int getMaxColumnsInGroupBy() throws SQLException { + return dbMetaData.getMaxColumnsInGroupBy(); + } + + @Override + public int getMaxColumnsInIndex() throws SQLException { + return dbMetaData.getMaxColumnsInIndex(); + } + + @Override + public int getMaxColumnsInOrderBy() throws SQLException { + return dbMetaData.getMaxColumnsInOrderBy(); + } + + @Override + public int getMaxColumnsInSelect() throws SQLException { + return dbMetaData.getMaxColumnsInSelect(); + } + + @Override + public int getMaxColumnsInTable() throws SQLException { + return dbMetaData.getMaxColumnsInTable(); + } + + @Override + public int getMaxConnections() throws SQLException { + return dbMetaData.getMaxConnections(); + } + + @Override + public int getMaxCursorNameLength() throws SQLException { + return dbMetaData.getMaxCursorNameLength(); + } + + @Override + public int getMaxIndexLength() throws SQLException { + return dbMetaData.getMaxIndexLength(); + } + + @Override + public int getMaxSchemaNameLength() throws SQLException { + return dbMetaData.getMaxSchemaNameLength(); + } + + @Override + public int getMaxProcedureNameLength() throws SQLException { + return dbMetaData.getMaxProcedureNameLength(); + } + + @Override + public int getMaxCatalogNameLength() throws SQLException { + return dbMetaData.getMaxCatalogNameLength(); + } + + @Override + public int getMaxRowSize() throws SQLException { + return dbMetaData.getMaxRowSize(); + } + + @Override + public boolean doesMaxRowSizeIncludeBlobs() throws SQLException { + return dbMetaData.doesMaxRowSizeIncludeBlobs(); + } + + @Override + public int getMaxStatementLength() throws SQLException { + return dbMetaData.getMaxStatementLength(); + } + + @Override + public int getMaxStatements() throws SQLException { + return dbMetaData.getMaxStatements(); + } + + @Override + public int getMaxTableNameLength() throws SQLException { + return dbMetaData.getMaxTableNameLength(); + } + + @Override + public int getMaxTablesInSelect() throws SQLException { + return dbMetaData.getMaxTablesInSelect(); + } + + @Override + public int getMaxUserNameLength() throws SQLException { + return dbMetaData.getMaxUserNameLength(); + } + + @Override + public int getDefaultTransactionIsolation() throws SQLException { + return dbMetaData.getDefaultTransactionIsolation(); + } + + @Override + public boolean supportsTransactions() throws SQLException { + return dbMetaData.supportsTransactions(); + } + + @Override + public boolean supportsTransactionIsolationLevel(int level) throws SQLException { + return dbMetaData.supportsTransactionIsolationLevel(level); + } + + @Override + public boolean supportsDataDefinitionAndDataManipulationTransactions() throws SQLException { + return dbMetaData.supportsDataDefinitionAndDataManipulationTransactions(); + } + + @Override + public boolean supportsDataManipulationTransactionsOnly() throws SQLException { + return dbMetaData.supportsDataManipulationTransactionsOnly(); + } + + @Override + public boolean dataDefinitionCausesTransactionCommit() throws SQLException { + return dbMetaData.dataDefinitionCausesTransactionCommit(); + } + + @Override + public boolean dataDefinitionIgnoredInTransactions() throws SQLException { + return dbMetaData.dataDefinitionIgnoredInTransactions(); + } + + @Override + public ResultSet getProcedures(String catalog, String schemaPattern, + String procedureNamePattern) throws SQLException { + return dbMetaData.getProcedures(catalog, schemaPattern, procedureNamePattern); + } + + @Override + public ResultSet getProcedureColumns(String catalog, String schemaPattern, + String procedureNamePattern, String columnNamePattern) + throws SQLException { + return dbMetaData.getProcedureColumns(catalog, schemaPattern, + procedureNamePattern, columnNamePattern); + } + + @Override + public ResultSet getTables(String catalog, String schemaPattern, + String tableNamePattern, String[] types) throws SQLException { + return dbMetaData.getTables(catalog, schemaPattern, tableNamePattern, types); + } + + @Override + public ResultSet getSchemas() throws SQLException { + return dbMetaData.getSchemas(); + } + + @Override + public ResultSet getCatalogs() throws SQLException { + return dbMetaData.getCatalogs(); + } + + @Override + public ResultSet getTableTypes() throws SQLException { + return dbMetaData.getTableTypes(); + } + + @Override + public ResultSet getColumns(String catalog, String schemaPattern, + String tableNamePattern, String columnNamePattern) + throws SQLException { + return dbMetaData.getColumns(catalog, schemaPattern, tableNamePattern, columnNamePattern); + } + + @Override + public ResultSet getColumnPrivileges(String catalog, String schema, + String table, String columnNamePattern) throws SQLException { + return dbMetaData.getColumnPrivileges(catalog, schema, table, columnNamePattern); + } + + @Override + public ResultSet getTablePrivileges(String catalog, String schemaPattern, + String tableNamePattern) throws SQLException { + return dbMetaData.getTablePrivileges(catalog, schemaPattern, tableNamePattern); + } + + @Override + public ResultSet getBestRowIdentifier(String catalog, String schema, + String table, int scope, boolean nullable) throws SQLException { + return dbMetaData.getBestRowIdentifier(catalog, schema, table, scope, nullable); + } + + @Override + public ResultSet getVersionColumns(String catalog, String schema, String table) throws SQLException { + return dbMetaData.getVersionColumns(catalog, schema, table); + } + + @Override + public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException { + return dbMetaData.getPrimaryKeys(catalog, schema, table); + } + + @Override + public ResultSet getImportedKeys(String catalog, String schema, String table) throws SQLException { + return dbMetaData.getImportedKeys(catalog, schema, table); + } + + @Override + public ResultSet getExportedKeys(String catalog, String schema, String table) throws SQLException { + return dbMetaData.getExportedKeys(catalog, schema, table); + } + + @Override + public ResultSet getCrossReference(String parentCatalog, + String parentSchema, String parentTable, String foreignCatalog, + String foreignSchema, String foreignTable) throws SQLException { + return dbMetaData.getCrossReference(parentCatalog, + parentSchema, parentTable, foreignCatalog, foreignSchema, foreignTable); + } + + @Override + public ResultSet getTypeInfo() throws SQLException { + return dbMetaData.getTypeInfo(); + } + + @Override + public ResultSet getIndexInfo(String catalog, String schema, String table, + boolean unique, boolean approximate) throws SQLException { + return dbMetaData.getIndexInfo(catalog, schema, table, unique, approximate); + } + + @Override + public boolean supportsResultSetType(int type) throws SQLException { + return dbMetaData.supportsResultSetType(type); + } + + @Override + public boolean supportsResultSetConcurrency(int type, int concurrency) throws SQLException { + return dbMetaData.supportsResultSetConcurrency(type, concurrency); + } + + @Override + public boolean ownUpdatesAreVisible(int type) throws SQLException { + return dbMetaData.ownUpdatesAreVisible(type); + } + + @Override + public boolean ownDeletesAreVisible(int type) throws SQLException { + return dbMetaData.ownDeletesAreVisible(type); + } + + @Override + public boolean ownInsertsAreVisible(int type) throws SQLException { + return dbMetaData.ownInsertsAreVisible(type); + } + + @Override + public boolean othersUpdatesAreVisible(int type) throws SQLException { + return dbMetaData.othersUpdatesAreVisible(type); + } + + @Override + public boolean othersDeletesAreVisible(int type) throws SQLException { + return dbMetaData.othersDeletesAreVisible(type); + } + + @Override + public boolean othersInsertsAreVisible(int type) throws SQLException { + return dbMetaData.othersInsertsAreVisible(type); + } + + @Override + public boolean updatesAreDetected(int type) throws SQLException { + return dbMetaData.updatesAreDetected(type); + } + + @Override + public boolean deletesAreDetected(int type) throws SQLException { + return dbMetaData.deletesAreDetected(type); + } + + @Override + public boolean insertsAreDetected(int type) throws SQLException { + return dbMetaData.insertsAreDetected(type); + } + + @Override + public boolean supportsBatchUpdates() throws SQLException { + return dbMetaData.supportsBatchUpdates(); + } + + @Override + public ResultSet getUDTs(String catalog, String schemaPattern, + String typeNamePattern, int[] types) throws SQLException { + return dbMetaData.getUDTs(catalog, schemaPattern, typeNamePattern, types); + } + + @Override + public Connection getConnection() throws SQLException { + return dbMetaData.getConnection(); + } + + @Override + public boolean supportsSavepoints() throws SQLException { + return dbMetaData.supportsSavepoints(); + } + + @Override + public boolean supportsNamedParameters() throws SQLException { + return dbMetaData.supportsNamedParameters(); + } + + @Override + public boolean supportsMultipleOpenResults() throws SQLException { + return dbMetaData.supportsMultipleOpenResults(); + } + + @Override + public boolean supportsGetGeneratedKeys() throws SQLException { + return dbMetaData.supportsGetGeneratedKeys(); + } + + @Override + public ResultSet getSuperTypes(String catalog, String schemaPattern, + String typeNamePattern) throws SQLException { + return dbMetaData.getSuperTypes(catalog, schemaPattern, typeNamePattern); + } + + @Override + public ResultSet getSuperTables(String catalog, String schemaPattern, + String tableNamePattern) throws SQLException { + return dbMetaData.getSuperTables(catalog, schemaPattern, tableNamePattern); + } + + @Override + public ResultSet getAttributes(String catalog, String schemaPattern, + String typeNamePattern, String attributeNamePattern) + throws SQLException { + return dbMetaData.getAttributes(catalog, schemaPattern, typeNamePattern, attributeNamePattern); + } + + @Override + public boolean supportsResultSetHoldability(int holdability) throws SQLException { + return dbMetaData.supportsResultSetHoldability(holdability); + } + + @Override + public int getResultSetHoldability() throws SQLException { + return dbMetaData.getResultSetHoldability(); + } + + @Override + public int getDatabaseMajorVersion() throws SQLException { + return dbMetaData.getDatabaseMajorVersion(); + } + + @Override + public int getDatabaseMinorVersion() throws SQLException { + return dbMetaData.getDatabaseMinorVersion(); + } + + @Override + public int getJDBCMajorVersion() throws SQLException { + return dbMetaData.getJDBCMajorVersion(); + } + + @Override + public int getJDBCMinorVersion() throws SQLException { + return dbMetaData.getJDBCMinorVersion(); + } + + @Override + public int getSQLStateType() throws SQLException { + return dbMetaData.getSQLStateType(); + } + + @Override + public boolean locatorsUpdateCopy() throws SQLException { + return dbMetaData.locatorsUpdateCopy(); + } + + @Override + public boolean supportsStatementPooling() throws SQLException { + return dbMetaData.supportsStatementPooling(); + } + + @Override + public RowIdLifetime getRowIdLifetime() throws SQLException { + return dbMetaData.getRowIdLifetime(); + } + + @Override + public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLException { + return dbMetaData.getSchemas(catalog, schemaPattern); + } + + @Override + public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException { + return dbMetaData.supportsStoredFunctionsUsingCallSyntax(); + } + + @Override + public boolean autoCommitFailureClosesAllResultSets() throws SQLException { + return dbMetaData.autoCommitFailureClosesAllResultSets(); + } + + @Override + public ResultSet getClientInfoProperties() throws SQLException { + return dbMetaData.getClientInfoProperties(); + } + + @Override + public ResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern) throws SQLException { + return dbMetaData.getFunctions(catalog, schemaPattern, functionNamePattern); + } + + @Override + public ResultSet getFunctionColumns(String catalog, String schemaPattern, + String functionNamePattern, String columnNamePattern) throws SQLException { + return dbMetaData.getFunctionColumns(catalog, schemaPattern, functionNamePattern, columnNamePattern); + } + + @Override + public ResultSet getPseudoColumns(String catalog, String schemaPattern, + String tableNamePattern, String columnNamePattern) throws SQLException { + return dbMetaData.getPseudoColumns(catalog, schemaPattern, tableNamePattern, columnNamePattern); + } + + @Override + public boolean generatedKeyAlwaysReturned() throws SQLException { + return dbMetaData.generatedKeyAlwaysReturned(); + } + +} diff --git a/src/main/java/com/crd/data/wrapper/PreparedStatementWrapper.java b/src/main/java/com/crd/data/wrapper/PreparedStatementWrapper.java new file mode 100644 index 000000000..9ad51186f --- /dev/null +++ b/src/main/java/com/crd/data/wrapper/PreparedStatementWrapper.java @@ -0,0 +1,552 @@ +/* Copyright (c) 2015 + * by Charles River Development, Inc., Burlington, MA + * + * This software is furnished under a license and may be used only in + * accordance with the terms of such license. This software may not be + * provided or otherwise made available to any other party. No title to + * nor ownership of the software is hereby transferred. + * + * This software is the intellectual property of Charles River Development, Inc., + * and is protected by the copyright laws of the United States of America. + * All rights reserved internationally. + * + */ + +package com.crd.data.wrapper; + +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.Connection; +import java.sql.DatabaseMetaData; +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.SQLWarning; +import java.sql.SQLXML; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.Calendar; + +/** + * Default wrapper around the PreparedStatement + * @author yshao + * + */ +public class PreparedStatementWrapper implements PreparedStatement { + + private final PreparedStatement pStatement; + + public PreparedStatementWrapper(PreparedStatement pStatement) { + this.pStatement = pStatement; + } + + @Override + public T unwrap(Class iface) throws SQLException { + if (isWrapperFor(iface)) { + return (T)pStatement; + } + throw new SQLException("This is not a wrapper of a PreparedStatement"); + } + + @Override + public boolean isWrapperFor(Class iface) throws SQLException { + return pStatement.isWrapperFor(iface); + } + + @Override + public ResultSet executeQuery(String sql) throws SQLException { + return pStatement.executeQuery(sql); + } + + @Override + public int executeUpdate(String sql) throws SQLException { + return pStatement.executeUpdate(sql); + } + + @Override + public void close() throws SQLException { + pStatement.close(); + } + + @Override + public int getMaxFieldSize() throws SQLException { + return pStatement.getMaxFieldSize(); + } + + @Override + public void setMaxFieldSize(int max) throws SQLException { + pStatement.setMaxFieldSize(max); + } + + @Override + public int getMaxRows() throws SQLException { + return pStatement.getMaxRows(); + } + + @Override + public void setMaxRows(int max) throws SQLException { + pStatement.setMaxRows(max); + } + + @Override + public void setEscapeProcessing(boolean enable) throws SQLException { + pStatement.setEscapeProcessing(enable); + } + + @Override + public int getQueryTimeout() throws SQLException { + return pStatement.getQueryTimeout(); + } + + @Override + public void setQueryTimeout(int seconds) throws SQLException { + pStatement.setQueryTimeout(seconds); + } + + @Override + public void cancel() throws SQLException { + pStatement.cancel(); + } + + @Override + public SQLWarning getWarnings() throws SQLException { + return pStatement.getWarnings(); + } + + @Override + public void clearWarnings() throws SQLException { + pStatement.clearWarnings(); + } + + @Override + public void setCursorName(String name) throws SQLException { + pStatement.setCursorName(name); + } + + @Override + public boolean execute(String sql) throws SQLException { + return pStatement.execute(sql); + } + + @Override + public ResultSet getResultSet() throws SQLException { + return pStatement.getResultSet(); + } + + @Override + public int getUpdateCount() throws SQLException { + return pStatement.getUpdateCount(); + } + + @Override + public boolean getMoreResults() throws SQLException { + return pStatement.getMoreResults(); + } + + @Override + public void setFetchDirection(int direction) throws SQLException { + pStatement.setFetchDirection(direction); + } + + @Override + public int getFetchDirection() throws SQLException { + return pStatement.getFetchDirection(); + } + + @Override + public void setFetchSize(int rows) throws SQLException { + pStatement.setFetchSize(rows); + } + + @Override + public int getFetchSize() throws SQLException { + return pStatement.getFetchSize(); + } + + @Override + public int getResultSetConcurrency() throws SQLException { + return pStatement.getResultSetConcurrency(); + } + + @Override + public int getResultSetType() throws SQLException { + return pStatement.getResultSetType(); + } + + @Override + public void addBatch(String sql) throws SQLException { + pStatement.addBatch(sql); + } + + @Override + public void clearBatch() throws SQLException { + pStatement.clearBatch(); + } + + @Override + public int[] executeBatch() throws SQLException { + return pStatement.executeBatch(); + } + + @Override + public Connection getConnection() throws SQLException { + return pStatement.getConnection(); + } + + @Override + public boolean getMoreResults(int current) throws SQLException { + return pStatement.getMoreResults(current); + } + + @Override + public ResultSet getGeneratedKeys() throws SQLException { + return pStatement.getGeneratedKeys(); + } + + @Override + public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { + return pStatement.executeUpdate(sql, autoGeneratedKeys); + } + + @Override + public int executeUpdate(String sql, int[] columnIndexes) throws SQLException { + return pStatement.executeUpdate(sql, columnIndexes); + } + + @Override + public int executeUpdate(String sql, String[] columnNames) throws SQLException { + return pStatement.executeUpdate(sql, columnNames); + } + + @Override + public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { + return pStatement.execute(sql, autoGeneratedKeys); + } + + @Override + public boolean execute(String sql, int[] columnIndexes) throws SQLException { + return pStatement.execute(sql, columnIndexes); + } + + @Override + public boolean execute(String sql, String[] columnNames) throws SQLException { + return pStatement.execute(sql, columnNames); + } + + @Override + public int getResultSetHoldability() throws SQLException { + return pStatement.getResultSetHoldability(); + } + + @Override + public boolean isClosed() throws SQLException { + return pStatement.isClosed(); + } + + @Override + public void setPoolable(boolean poolable) throws SQLException { + pStatement.setPoolable(poolable); + } + + @Override + public boolean isPoolable() throws SQLException { + return pStatement.isPoolable(); + } + + @Override + public void closeOnCompletion() throws SQLException { + pStatement.closeOnCompletion(); + } + + @Override + public boolean isCloseOnCompletion() throws SQLException { + return pStatement.isCloseOnCompletion(); + } + + @Override + public ResultSet executeQuery() throws SQLException { + return pStatement.executeQuery(); + } + + @Override + public int executeUpdate() throws SQLException { + return pStatement.executeUpdate(); + } + + @Override + public void setNull(int parameterIndex, int sqlType) throws SQLException { + pStatement.setNull(parameterIndex, sqlType); + } + + @Override + public void setBoolean(int parameterIndex, boolean x) throws SQLException { + pStatement.setBoolean(parameterIndex, x); + } + + @Override + public void setByte(int parameterIndex, byte x) throws SQLException { + pStatement.setByte(parameterIndex, x); + } + + @Override + public void setShort(int parameterIndex, short x) throws SQLException { + pStatement.setShort(parameterIndex, x); + } + + @Override + public void setInt(int parameterIndex, int x) throws SQLException { + pStatement.setInt(parameterIndex, x); + } + + @Override + public void setLong(int parameterIndex, long x) throws SQLException { + pStatement.setLong(parameterIndex, x); + } + + @Override + public void setFloat(int parameterIndex, float x) throws SQLException { + pStatement.setFloat(parameterIndex, x); + } + + @Override + public void setDouble(int parameterIndex, double x) throws SQLException { + pStatement.setDouble(parameterIndex, x); + } + + @Override + public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException { + pStatement.setBigDecimal(parameterIndex, x); + } + + @Override + public void setString(int parameterIndex, String x) throws SQLException { + pStatement.setString(parameterIndex, x); + } + + @Override + public void setBytes(int parameterIndex, byte[] x) throws SQLException { + pStatement.setBytes(parameterIndex, x); + } + + @Override + public void setDate(int parameterIndex, Date x) throws SQLException { + pStatement.setDate(parameterIndex, x); + } + + @Override + public void setTime(int parameterIndex, Time x) throws SQLException { + pStatement.setTime(parameterIndex, x); + } + + @Override + public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException { + pStatement.setTimestamp(parameterIndex, x); + } + + @Override + public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException { + pStatement.setAsciiStream(parameterIndex, x, length); + } + + @Override + @Deprecated + public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException { + pStatement.setUnicodeStream(parameterIndex, x, length); + } + + @Override + public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException { + pStatement.setBinaryStream(parameterIndex, x, length); + } + + @Override + public void clearParameters() throws SQLException { + pStatement.clearParameters(); + } + + @Override + public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException { + pStatement.setObject(parameterIndex, x, targetSqlType); + } + + @Override + public void setObject(int parameterIndex, Object x) throws SQLException { + pStatement.setObject(parameterIndex, x); + } + + @Override + public boolean execute() throws SQLException { + return pStatement.execute(); + } + + @Override + public void addBatch() throws SQLException { + pStatement.addBatch(); + } + + @Override + public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException { + pStatement.setCharacterStream(parameterIndex, reader, length); + } + + @Override + public void setRef(int parameterIndex, Ref x) throws SQLException { + pStatement.setRef(parameterIndex, x); + } + + @Override + public void setBlob(int parameterIndex, Blob x) throws SQLException { + pStatement.setBlob(parameterIndex, x); + } + + @Override + public void setClob(int parameterIndex, Clob x) throws SQLException { + pStatement.setClob(parameterIndex, x); + } + + @Override + public void setArray(int parameterIndex, Array x) throws SQLException { + pStatement.setArray(parameterIndex, x); + } + + @Override + public ResultSetMetaData getMetaData() throws SQLException { + return pStatement.getMetaData(); + } + + @Override + public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException { + pStatement.setDate(parameterIndex, x, cal); + } + + @Override + public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException { + pStatement.setTime(parameterIndex, x, cal); + } + + @Override + public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException { + pStatement.setTimestamp(parameterIndex, x, cal); + } + + @Override + public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException { + pStatement.setNull(parameterIndex, sqlType, typeName); + } + + @Override + public void setURL(int parameterIndex, URL x) throws SQLException { + pStatement.setURL(parameterIndex, x); + } + + @Override + public ParameterMetaData getParameterMetaData() throws SQLException { + return pStatement.getParameterMetaData(); + } + + @Override + public void setRowId(int parameterIndex, RowId x) throws SQLException { + pStatement.setRowId(parameterIndex, x); + } + + @Override + public void setNString(int parameterIndex, String value) throws SQLException { + pStatement.setNString(parameterIndex, value); + } + + @Override + public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException { + pStatement.setNCharacterStream(parameterIndex, value, length); + } + + @Override + public void setNClob(int parameterIndex, NClob value) throws SQLException { + pStatement.setNClob(parameterIndex, value); + } + + @Override + public void setClob(int parameterIndex, Reader reader, long length) throws SQLException { + pStatement.setClob(parameterIndex, reader, length); + } + + @Override + public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException { + pStatement.setBlob(parameterIndex, inputStream, length); + } + + @Override + public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException { + pStatement.setNClob(parameterIndex, reader, length); + } + + @Override + public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException { + pStatement.setSQLXML(parameterIndex, xmlObject); + } + + @Override + public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException { + pStatement.setObject(parameterIndex, x, targetSqlType, scaleOrLength); + } + + @Override + public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException { + pStatement.setAsciiStream(parameterIndex, x, length); + } + + @Override + public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException { + pStatement.setBinaryStream(parameterIndex, x, length); + } + + @Override + public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException { + pStatement.setCharacterStream(parameterIndex, reader, length); + } + + @Override + public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException { + pStatement.setAsciiStream(parameterIndex, x); + } + + @Override + public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException { + pStatement.setBinaryStream(parameterIndex, x); + } + + @Override + public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException { + pStatement.setCharacterStream(parameterIndex, reader); + } + + @Override + public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException { + pStatement.setNCharacterStream(parameterIndex, value); + } + + @Override + public void setClob(int parameterIndex, Reader reader) throws SQLException { + pStatement.setClob(parameterIndex, reader); + } + + @Override + public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException { + pStatement.setBlob(parameterIndex, inputStream); + } + + @Override + public void setNClob(int parameterIndex, Reader reader) throws SQLException { + pStatement.setNClob(parameterIndex, reader); + } +} diff --git a/src/main/java/com/crd/data/wrapper/ResultSetMetaDataWrapper.java b/src/main/java/com/crd/data/wrapper/ResultSetMetaDataWrapper.java new file mode 100644 index 000000000..6d11f9a73 --- /dev/null +++ b/src/main/java/com/crd/data/wrapper/ResultSetMetaDataWrapper.java @@ -0,0 +1,152 @@ +/* Copyright (c) 2015 + * by Charles River Development, Inc., Burlington, MA + * + * This software is furnished under a license and may be used only in + * accordance with the terms of such license. This software may not be + * provided or otherwise made available to any other party. No title to + * nor ownership of the software is hereby transferred. + * + * This software is the intellectual property of Charles River Development, Inc., + * and is protected by the copyright laws of the United States of America. + * All rights reserved internationally. + * + */ + +package com.crd.data.wrapper; + +import java.sql.Connection; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; + +/** + * Default wrapper around the ResultSetMetaData + * @author yshao + * + */ +public class ResultSetMetaDataWrapper implements ResultSetMetaData { + + private final ResultSetMetaData rsMetaData; + + public ResultSetMetaDataWrapper(ResultSetMetaData rsMetaData) { + this.rsMetaData = rsMetaData; + } + + @Override + public T unwrap(Class iface) throws SQLException { + if (isWrapperFor(iface)) { + return (T)rsMetaData; + } + throw new SQLException("This is not a wrapper of a ResultSetMetaData"); + } + + @Override + public boolean isWrapperFor(Class iface) throws SQLException { + return rsMetaData.isWrapperFor(iface); + } + + @Override + public int getColumnCount() throws SQLException { + return rsMetaData.getColumnCount(); + } + + @Override + public boolean isAutoIncrement(int column) throws SQLException { + return rsMetaData.isAutoIncrement(column); + } + + @Override + public boolean isCaseSensitive(int column) throws SQLException { + return rsMetaData.isCaseSensitive(column); + } + + @Override + public boolean isSearchable(int column) throws SQLException { + return rsMetaData.isSearchable(column); + } + + @Override + public boolean isCurrency(int column) throws SQLException { + return rsMetaData.isCurrency(column); + } + + @Override + public int isNullable(int column) throws SQLException { + return rsMetaData.isNullable(column); + } + + @Override + public boolean isSigned(int column) throws SQLException { + return rsMetaData.isSigned(column); + } + + @Override + public int getColumnDisplaySize(int column) throws SQLException { + return rsMetaData.getColumnDisplaySize(column); + } + + @Override + public String getColumnLabel(int column) throws SQLException { + return rsMetaData.getColumnLabel(column); + } + + @Override + public String getColumnName(int column) throws SQLException { + return rsMetaData.getColumnName(column); + } + + @Override + public String getSchemaName(int column) throws SQLException { + return rsMetaData.getSchemaName(column); + } + + @Override + public int getPrecision(int column) throws SQLException { + return rsMetaData.getPrecision(column); + } + + @Override + public int getScale(int column) throws SQLException { + return rsMetaData.getScale(column); + } + + @Override + public String getTableName(int column) throws SQLException { + return rsMetaData.getTableName(column); + } + + @Override + public String getCatalogName(int column) throws SQLException { + return rsMetaData.getCatalogName(column); + } + + @Override + public int getColumnType(int column) throws SQLException { + return rsMetaData.getColumnType(column); + } + + @Override + public String getColumnTypeName(int column) throws SQLException { + return rsMetaData.getColumnTypeName(column); + } + + @Override + public boolean isReadOnly(int column) throws SQLException { + return rsMetaData.isReadOnly(column); + } + + @Override + public boolean isWritable(int column) throws SQLException { + return rsMetaData.isWritable(column); + } + + @Override + public boolean isDefinitelyWritable(int column) throws SQLException { + return rsMetaData.isDefinitelyWritable(column); + } + + @Override + public String getColumnClassName(int column) throws SQLException { + return rsMetaData.getColumnClassName(column); + } + +} diff --git a/src/main/java/com/crd/data/wrapper/ResultSetWrapper.java b/src/main/java/com/crd/data/wrapper/ResultSetWrapper.java new file mode 100644 index 000000000..b85448c1b --- /dev/null +++ b/src/main/java/com/crd/data/wrapper/ResultSetWrapper.java @@ -0,0 +1,1013 @@ +/* Copyright (c) 2015 + * by Charles River Development, Inc., Burlington, MA + * + * This software is furnished under a license and may be used only in + * accordance with the terms of such license. This software may not be + * provided or otherwise made available to any other party. No title to + * nor ownership of the software is hereby transferred. + * + * This software is the intellectual property of Charles River Development, Inc., + * and is protected by the copyright laws of the United States of America. + * All rights reserved internationally. + * + */ + +package com.crd.data.wrapper; + +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.Ref; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.RowId; +import java.sql.SQLException; +import java.sql.SQLWarning; +import java.sql.SQLXML; +import java.sql.Statement; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.Calendar; +import java.util.Map; + +/** + * Default wrapper around the ResultSet + * @author yshao + * + */ +public class ResultSetWrapper implements ResultSet { + + private final ResultSet resultSet; + + public ResultSetWrapper(ResultSet resultSet) { + this.resultSet = resultSet; + } + + @Override + public T unwrap(Class iface) throws SQLException { + if (isWrapperFor(iface)) { + return (T)resultSet; + } + throw new SQLException("This is not a wrapper of a ResultSet"); + } + + @Override + public boolean isWrapperFor(Class iface) throws SQLException { + return resultSet.isWrapperFor(iface); + } + + @Override + public boolean next() throws SQLException { + return resultSet.next(); + } + + @Override + public void close() throws SQLException { + resultSet.close(); + } + + @Override + public boolean wasNull() throws SQLException { + return resultSet.wasNull(); + } + + @Override + public String getString(int columnIndex) throws SQLException { + return resultSet.getString(columnIndex); + } + + @Override + public boolean getBoolean(int columnIndex) throws SQLException { + return resultSet.getBoolean(columnIndex); + } + + @Override + public byte getByte(int columnIndex) throws SQLException { + return resultSet.getByte(columnIndex); + } + + @Override + public short getShort(int columnIndex) throws SQLException { + return resultSet.getShort(columnIndex); + } + + @Override + public int getInt(int columnIndex) throws SQLException { + return resultSet.getInt(columnIndex); + } + + @Override + public long getLong(int columnIndex) throws SQLException { + return resultSet.getLong(columnIndex); + } + + @Override + public float getFloat(int columnIndex) throws SQLException { + return resultSet.getFloat(columnIndex); + } + + @Override + public double getDouble(int columnIndex) throws SQLException { + return resultSet.getDouble(columnIndex); + } + + @Override + @Deprecated + public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException { + return resultSet.getBigDecimal(columnIndex, scale); + } + + @Override + public byte[] getBytes(int columnIndex) throws SQLException { + return resultSet.getBytes(columnIndex); + } + + @Override + public Date getDate(int columnIndex) throws SQLException { + return resultSet.getDate(columnIndex); + } + + @Override + public Time getTime(int columnIndex) throws SQLException { + return resultSet.getTime(columnIndex); + } + + @Override + public Timestamp getTimestamp(int columnIndex) throws SQLException { + return resultSet.getTimestamp(columnIndex); + } + + @Override + public InputStream getAsciiStream(int columnIndex) throws SQLException { + return resultSet.getAsciiStream(columnIndex); + } + + @Override + @Deprecated + public InputStream getUnicodeStream(int columnIndex) throws SQLException { + return resultSet.getUnicodeStream(columnIndex); + } + + @Override + public InputStream getBinaryStream(int columnIndex) throws SQLException { + return resultSet.getBinaryStream(columnIndex); + } + + @Override + public String getString(String columnLabel) throws SQLException { + return resultSet.getString(columnLabel); + } + + @Override + public boolean getBoolean(String columnLabel) throws SQLException { + return resultSet.getBoolean(columnLabel); + } + + @Override + public byte getByte(String columnLabel) throws SQLException { + return resultSet.getByte(columnLabel); + } + + @Override + public short getShort(String columnLabel) throws SQLException { + return resultSet.getShort(columnLabel); + } + + @Override + public int getInt(String columnLabel) throws SQLException { + return resultSet.getInt(columnLabel); + } + + @Override + public long getLong(String columnLabel) throws SQLException { + return resultSet.getLong(columnLabel); + } + + @Override + public float getFloat(String columnLabel) throws SQLException { + return resultSet.getFloat(columnLabel); + } + + @Override + public double getDouble(String columnLabel) throws SQLException { + return resultSet.getDouble(columnLabel); + } + + @Override + @Deprecated + public BigDecimal getBigDecimal(String columnLabel, int scale)throws SQLException { + return resultSet.getBigDecimal(columnLabel, scale); + } + + @Override + public byte[] getBytes(String columnLabel) throws SQLException { + return resultSet.getBytes(columnLabel); + } + + @Override + public Date getDate(String columnLabel) throws SQLException { + return resultSet.getDate(columnLabel); + } + + @Override + public Time getTime(String columnLabel) throws SQLException { + return resultSet.getTime(columnLabel); + } + + @Override + public Timestamp getTimestamp(String columnLabel) throws SQLException { + return resultSet.getTimestamp(columnLabel); + } + + @Override + public InputStream getAsciiStream(String columnLabel) throws SQLException { + return resultSet.getAsciiStream(columnLabel); + } + + @Override + @Deprecated + public InputStream getUnicodeStream(String columnLabel) throws SQLException { + return resultSet.getUnicodeStream(columnLabel); + } + + @Override + public InputStream getBinaryStream(String columnLabel) throws SQLException { + return resultSet.getBinaryStream(columnLabel); + } + + @Override + public SQLWarning getWarnings() throws SQLException { + return resultSet.getWarnings(); + } + + @Override + public void clearWarnings() throws SQLException { + resultSet.clearWarnings(); + } + + @Override + public String getCursorName() throws SQLException { + return resultSet.getCursorName(); + } + + @Override + public ResultSetMetaData getMetaData() throws SQLException { + return resultSet.getMetaData(); + } + + @Override + public Object getObject(int columnIndex) throws SQLException { + return resultSet.getObject(columnIndex); + } + + @Override + public Object getObject(String columnLabel) throws SQLException { + return resultSet.getObject(columnLabel); + } + + @Override + public int findColumn(String columnLabel) throws SQLException { + return resultSet.findColumn(columnLabel); + } + + @Override + public Reader getCharacterStream(int columnIndex) throws SQLException { + return resultSet.getCharacterStream(columnIndex); + } + + @Override + public Reader getCharacterStream(String columnLabel) throws SQLException { + return resultSet.getCharacterStream(columnLabel); + } + + @Override + public BigDecimal getBigDecimal(int columnIndex) throws SQLException { + return resultSet.getBigDecimal(columnIndex); + } + + @Override + public BigDecimal getBigDecimal(String columnLabel) throws SQLException { + return resultSet.getBigDecimal(columnLabel); + } + + @Override + public boolean isBeforeFirst() throws SQLException { + return resultSet.isBeforeFirst(); + } + + @Override + public boolean isAfterLast() throws SQLException { + return resultSet.isAfterLast(); + } + + @Override + public boolean isFirst() throws SQLException { + return resultSet.isFirst(); + } + + @Override + public boolean isLast() throws SQLException { + return resultSet.isLast(); + } + + @Override + public void beforeFirst() throws SQLException { + resultSet.beforeFirst(); + } + + @Override + public void afterLast() throws SQLException { + resultSet.afterLast(); + } + + @Override + public boolean first() throws SQLException { + return resultSet.first(); + } + + @Override + public boolean last() throws SQLException { + return resultSet.last(); + } + + @Override + public int getRow() throws SQLException { + return resultSet.getRow(); + } + + @Override + public boolean absolute(int row) throws SQLException { + return resultSet.absolute(row); + } + + @Override + public boolean relative(int rows) throws SQLException { + return resultSet.relative(rows); + } + + @Override + public boolean previous() throws SQLException { + return resultSet.previous(); + } + + @Override + public void setFetchDirection(int direction) throws SQLException { + resultSet.setFetchDirection(direction); + } + + @Override + public int getFetchDirection() throws SQLException { + return resultSet.getFetchDirection(); + } + + @Override + public void setFetchSize(int rows) throws SQLException { + resultSet.setFetchSize(rows); + } + + @Override + public int getFetchSize() throws SQLException { + return resultSet.getFetchSize(); + } + + @Override + public int getType() throws SQLException { + return resultSet.getType(); + } + + @Override + public int getConcurrency() throws SQLException { + return resultSet.getConcurrency(); + } + + @Override + public boolean rowUpdated() throws SQLException { + return resultSet.rowUpdated(); + } + + @Override + public boolean rowInserted() throws SQLException { + return resultSet.rowInserted(); + } + + @Override + public boolean rowDeleted() throws SQLException { + return resultSet.rowDeleted(); + } + + @Override + public void updateNull(int columnIndex) throws SQLException { + resultSet.updateNull(columnIndex); + } + + @Override + public void updateBoolean(int columnIndex, boolean x) throws SQLException { + resultSet.updateBoolean(columnIndex, x); + } + + @Override + public void updateByte(int columnIndex, byte x) throws SQLException { + resultSet.updateByte(columnIndex, x); + } + + @Override + public void updateShort(int columnIndex, short x) throws SQLException { + resultSet.updateShort(columnIndex, x); + } + + @Override + public void updateInt(int columnIndex, int x) throws SQLException { + resultSet.updateInt(columnIndex, x); + } + + @Override + public void updateLong(int columnIndex, long x) throws SQLException { + resultSet.updateLong(columnIndex, x); + } + + @Override + public void updateFloat(int columnIndex, float x) throws SQLException { + resultSet.updateFloat(columnIndex, x); + } + + @Override + public void updateDouble(int columnIndex, double x) throws SQLException { + resultSet.updateDouble(columnIndex, x); + } + + @Override + public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException { + resultSet.updateBigDecimal(columnIndex, x); + } + + @Override + public void updateString(int columnIndex, String x) throws SQLException { + resultSet.updateString(columnIndex, x); + } + + @Override + public void updateBytes(int columnIndex, byte[] x) throws SQLException { + resultSet.updateBytes(columnIndex, x); + } + + @Override + public void updateDate(int columnIndex, Date x) throws SQLException { + resultSet.updateDate(columnIndex, x); + } + + @Override + public void updateTime(int columnIndex, Time x) throws SQLException { + resultSet.updateTime(columnIndex, x); + } + + @Override + public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException { + resultSet.updateTimestamp(columnIndex, x); + } + + @Override + public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException { + resultSet.updateAsciiStream(columnIndex, x, length); + } + + @Override + public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException { + resultSet.updateBinaryStream(columnIndex, x, length); + } + + @Override + public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException { + resultSet.updateCharacterStream(columnIndex, x, length); + } + + @Override + public void updateObject(int columnIndex, Object x, int scaleOrLength) throws SQLException { + resultSet.updateObject(columnIndex, x, scaleOrLength); + } + + @Override + public void updateObject(int columnIndex, Object x) throws SQLException { + resultSet.updateObject(columnIndex, x); + } + + @Override + public void updateNull(String columnLabel) throws SQLException { + resultSet.updateNull(columnLabel); + } + + @Override + public void updateBoolean(String columnLabel, boolean x) throws SQLException { + resultSet.updateBoolean(columnLabel, x); + } + + @Override + public void updateByte(String columnLabel, byte x) throws SQLException { + resultSet.updateByte(columnLabel, x); + } + + @Override + public void updateShort(String columnLabel, short x) throws SQLException { + resultSet.updateShort(columnLabel, x); + } + + @Override + public void updateInt(String columnLabel, int x) throws SQLException { + resultSet.updateInt(columnLabel, x); + } + + @Override + public void updateLong(String columnLabel, long x) throws SQLException { + resultSet.updateLong(columnLabel, x); + } + + @Override + public void updateFloat(String columnLabel, float x) throws SQLException { + resultSet.updateFloat(columnLabel, x); + } + + @Override + public void updateDouble(String columnLabel, double x) throws SQLException { + resultSet.updateDouble(columnLabel, x); + } + + @Override + public void updateBigDecimal(String columnLabel, BigDecimal x) throws SQLException { + resultSet.updateBigDecimal(columnLabel, x); + } + + @Override + public void updateString(String columnLabel, String x) throws SQLException { + resultSet.updateString(columnLabel, x); + } + + @Override + public void updateBytes(String columnLabel, byte[] x) throws SQLException { + resultSet.updateBytes(columnLabel, x); + } + + @Override + public void updateDate(String columnLabel, Date x) throws SQLException { + resultSet.updateDate(columnLabel, x); + } + + @Override + public void updateTime(String columnLabel, Time x) throws SQLException { + resultSet.updateTime(columnLabel, x); + } + + @Override + public void updateTimestamp(String columnLabel, Timestamp x) throws SQLException { + resultSet.updateTimestamp(columnLabel, x); + } + + @Override + public void updateAsciiStream(String columnLabel, InputStream x, int length) throws SQLException { + resultSet.updateAsciiStream(columnLabel, x, length); + } + + @Override + public void updateBinaryStream(String columnLabel, InputStream x, int length) throws SQLException { + resultSet.updateBinaryStream(columnLabel, x, length); + } + + @Override + public void updateCharacterStream(String columnLabel, Reader reader, int length) throws SQLException { + resultSet.updateCharacterStream(columnLabel, reader, length); + } + + @Override + public void updateObject(String columnLabel, Object x, int scaleOrLength) throws SQLException { + resultSet.updateObject(columnLabel, x, scaleOrLength); + } + + @Override + public void updateObject(String columnLabel, Object x) throws SQLException { + resultSet.updateObject(columnLabel, x); + } + + @Override + public void insertRow() throws SQLException { + resultSet.insertRow(); + } + + @Override + public void updateRow() throws SQLException { + resultSet.updateRow(); + } + + @Override + public void deleteRow() throws SQLException { + resultSet.deleteRow(); + } + + @Override + public void refreshRow() throws SQLException { + resultSet.refreshRow(); + } + + @Override + public void cancelRowUpdates() throws SQLException { + resultSet.cancelRowUpdates(); + } + + @Override + public void moveToInsertRow() throws SQLException { + resultSet.moveToInsertRow(); + } + + @Override + public void moveToCurrentRow() throws SQLException { + resultSet.moveToCurrentRow(); + } + + @Override + public Statement getStatement() throws SQLException { + return resultSet.getStatement(); + } + + @Override + public Object getObject(int columnIndex, Map> map) throws SQLException { + return resultSet.getObject(columnIndex, map); + } + + @Override + public Ref getRef(int columnIndex) throws SQLException { + return resultSet.getRef(columnIndex); + } + + @Override + public Blob getBlob(int columnIndex) throws SQLException { + return resultSet.getBlob(columnIndex); + } + + @Override + public Clob getClob(int columnIndex) throws SQLException { + return resultSet.getClob(columnIndex); + } + + @Override + public Array getArray(int columnIndex) throws SQLException { + return resultSet.getArray(columnIndex); + } + + @Override + public Object getObject(String columnLabel, Map> map) throws SQLException { + return resultSet.getObject(columnLabel, map); + } + + @Override + public Ref getRef(String columnLabel) throws SQLException { + return resultSet.getRef(columnLabel); + } + + @Override + public Blob getBlob(String columnLabel) throws SQLException { + return resultSet.getBlob(columnLabel); + } + + @Override + public Clob getClob(String columnLabel) throws SQLException { + return resultSet.getClob(columnLabel); + } + + @Override + public Array getArray(String columnLabel) throws SQLException { + return resultSet.getArray(columnLabel); + } + + @Override + public Date getDate(int columnIndex, Calendar cal) throws SQLException { + return resultSet.getDate(columnIndex, cal); + } + + @Override + public Date getDate(String columnLabel, Calendar cal) throws SQLException { + return resultSet.getDate(columnLabel, cal); + } + + @Override + public Time getTime(int columnIndex, Calendar cal) throws SQLException { + return resultSet.getTime(columnIndex, cal); + } + + @Override + public Time getTime(String columnLabel, Calendar cal) throws SQLException { + return resultSet.getTime(columnLabel, cal); + } + + @Override + public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException { + return resultSet.getTimestamp(columnIndex, cal); + } + + @Override + public Timestamp getTimestamp(String columnLabel, Calendar cal) throws SQLException { + return resultSet.getTimestamp(columnLabel, cal); + } + + @Override + public URL getURL(int columnIndex) throws SQLException { + return resultSet.getURL(columnIndex); + } + + @Override + public URL getURL(String columnLabel) throws SQLException { + return resultSet.getURL(columnLabel); + } + + @Override + public void updateRef(int columnIndex, Ref x) throws SQLException { + resultSet.updateRef(columnIndex, x); + } + + @Override + public void updateRef(String columnLabel, Ref x) throws SQLException { + resultSet.updateRef(columnLabel, x); + } + + @Override + public void updateBlob(int columnIndex, Blob x) throws SQLException { + resultSet.updateBlob(columnIndex, x); + } + + @Override + public void updateBlob(String columnLabel, Blob x) throws SQLException { + resultSet.updateBlob(columnLabel, x); + } + + @Override + public void updateClob(int columnIndex, Clob x) throws SQLException { + resultSet.updateClob(columnIndex, x); + } + + @Override + public void updateClob(String columnLabel, Clob x) throws SQLException { + resultSet.updateClob(columnLabel, x); + } + + @Override + public void updateArray(int columnIndex, Array x) throws SQLException { + resultSet.updateArray(columnIndex, x); + } + + @Override + public void updateArray(String columnLabel, Array x) throws SQLException { + resultSet.updateArray(columnLabel, x); + } + + @Override + public RowId getRowId(int columnIndex) throws SQLException { + return resultSet.getRowId(columnIndex); + } + + @Override + public RowId getRowId(String columnLabel) throws SQLException { + return resultSet.getRowId(columnLabel); + } + + @Override + public void updateRowId(int columnIndex, RowId x) throws SQLException { + resultSet.updateRowId(columnIndex, x); + } + + @Override + public void updateRowId(String columnLabel, RowId x) throws SQLException { + resultSet.updateRowId(columnLabel, x); + } + + @Override + public int getHoldability() throws SQLException { + return resultSet.getHoldability(); + } + + @Override + public boolean isClosed() throws SQLException { + return resultSet.isClosed(); + } + + @Override + public void updateNString(int columnIndex, String nString) throws SQLException { + resultSet.updateNString(columnIndex, nString); + } + + @Override + public void updateNString(String columnLabel, String nString) throws SQLException { + resultSet.updateNString(columnLabel, nString); + } + + @Override + public void updateNClob(int columnIndex, NClob nClob) throws SQLException { + resultSet.updateNClob(columnIndex, nClob); + } + + @Override + public void updateNClob(String columnLabel, NClob nClob) throws SQLException { + resultSet.updateNClob(columnLabel, nClob); + } + + @Override + public NClob getNClob(int columnIndex) throws SQLException { + return resultSet.getNClob(columnIndex); + } + + @Override + public NClob getNClob(String columnLabel) throws SQLException { + return resultSet.getNClob(columnLabel); + } + + @Override + public SQLXML getSQLXML(int columnIndex) throws SQLException { + return resultSet.getSQLXML(columnIndex); + } + + @Override + public SQLXML getSQLXML(String columnLabel) throws SQLException { + return resultSet.getSQLXML(columnLabel); + } + + @Override + public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException { + resultSet.updateSQLXML(columnIndex, xmlObject); + } + + @Override + public void updateSQLXML(String columnLabel, SQLXML xmlObject) throws SQLException { + resultSet.updateSQLXML(columnLabel, xmlObject); + } + + @Override + public String getNString(int columnIndex) throws SQLException { + return resultSet.getNString(columnIndex); + } + + @Override + public String getNString(String columnLabel) throws SQLException { + return resultSet.getNString(columnLabel); + } + + @Override + public Reader getNCharacterStream(int columnIndex) throws SQLException { + return resultSet.getNCharacterStream(columnIndex); + } + + @Override + public Reader getNCharacterStream(String columnLabel) throws SQLException { + return resultSet.getNCharacterStream(columnLabel); + } + + @Override + public void updateNCharacterStream(int columnIndex, Reader x, long length) throws SQLException { + resultSet.updateNCharacterStream(columnIndex, x, length); + } + + @Override + public void updateNCharacterStream(String columnLabel, Reader reader, long length) throws SQLException { + resultSet.updateNCharacterStream(columnLabel, reader, length); + } + + @Override + public void updateAsciiStream(int columnIndex, InputStream x, long length) throws SQLException { + resultSet.updateAsciiStream(columnIndex, x, length); + } + + @Override + public void updateBinaryStream(int columnIndex, InputStream x, long length) throws SQLException { + resultSet.updateBinaryStream(columnIndex, x, length); + } + + @Override + public void updateCharacterStream(int columnIndex, Reader x, long length) throws SQLException { + resultSet.updateCharacterStream(columnIndex, x, length); + } + + @Override + public void updateAsciiStream(String columnLabel, InputStream x, long length) throws SQLException { + resultSet.updateAsciiStream(columnLabel, x, length); + } + + @Override + public void updateBinaryStream(String columnLabel, InputStream x, long length) throws SQLException { + resultSet.updateBinaryStream(columnLabel, x, length); + } + + @Override + public void updateCharacterStream(String columnLabel, Reader reader, long length) throws SQLException { + resultSet.updateCharacterStream(columnLabel, reader, length); + } + + @Override + public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException { + resultSet.updateBlob(columnIndex, inputStream, length); + } + + @Override + public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException { + resultSet.updateBlob(columnLabel, inputStream, length); + } + + @Override + public void updateClob(int columnIndex, Reader reader, long length) throws SQLException { + resultSet.updateClob(columnIndex, reader, length); + } + + @Override + public void updateClob(String columnLabel, Reader reader, long length) throws SQLException { + resultSet.updateClob(columnLabel, reader, length); + } + + @Override + public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException { + resultSet.updateNClob(columnIndex, reader, length); + } + + @Override + public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException { + resultSet.updateNClob(columnLabel, reader, length); + } + + @Override + public void updateNCharacterStream(int columnIndex, Reader x) throws SQLException { + resultSet.updateNCharacterStream(columnIndex, x); + } + + @Override + public void updateNCharacterStream(String columnLabel, Reader reader) throws SQLException { + resultSet.updateNCharacterStream(columnLabel, reader); + } + + @Override + public void updateAsciiStream(int columnIndex, InputStream x) throws SQLException { + resultSet.updateAsciiStream(columnIndex, x); + } + + @Override + public void updateBinaryStream(int columnIndex, InputStream x) throws SQLException { + resultSet.updateBinaryStream(columnIndex, x); + } + + @Override + public void updateCharacterStream(int columnIndex, Reader x) throws SQLException { + resultSet.updateCharacterStream(columnIndex, x); + } + + @Override + public void updateAsciiStream(String columnLabel, InputStream x) throws SQLException { + resultSet.updateAsciiStream(columnLabel, x); + } + + @Override + public void updateBinaryStream(String columnLabel, InputStream x) throws SQLException { + resultSet.updateBinaryStream(columnLabel, x); + } + + @Override + public void updateCharacterStream(String columnLabel, Reader reader) throws SQLException { + resultSet.updateCharacterStream(columnLabel, reader); + } + + @Override + public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException { + resultSet.updateBlob(columnIndex, inputStream); + } + + @Override + public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException { + resultSet.updateBlob(columnLabel, inputStream); + } + + @Override + public void updateClob(int columnIndex, Reader reader) throws SQLException { + resultSet.updateClob(columnIndex, reader); + } + + @Override + public void updateClob(String columnLabel, Reader reader) throws SQLException { + resultSet.updateClob(columnLabel, reader); + } + + @Override + public void updateNClob(int columnIndex, Reader reader) throws SQLException { + resultSet.updateNClob(columnIndex, reader); + } + + @Override + public void updateNClob(String columnLabel, Reader reader) throws SQLException { + resultSet.updateNClob(columnLabel, reader); + } + + @Override + public T getObject(int columnIndex, Class type) throws SQLException { + return resultSet.getObject(columnIndex, type); + } + + @Override + public T getObject(String columnLabel, Class type) throws SQLException { + return resultSet.getObject(columnLabel, type); + } +} diff --git a/src/main/java/com/crd/data/wrapper/StatementWrapper.java b/src/main/java/com/crd/data/wrapper/StatementWrapper.java new file mode 100644 index 000000000..e12ce2561 --- /dev/null +++ b/src/main/java/com/crd/data/wrapper/StatementWrapper.java @@ -0,0 +1,259 @@ +/* Copyright (c) 2015 + * by Charles River Development, Inc., Burlington, MA + * + * This software is furnished under a license and may be used only in + * accordance with the terms of such license. This software may not be + * provided or otherwise made available to any other party. No title to + * nor ownership of the software is hereby transferred. + * + * This software is the intellectual property of Charles River Development, Inc., + * and is protected by the copyright laws of the United States of America. + * All rights reserved internationally. + * + */ + +package com.crd.data.wrapper; + + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.SQLWarning; +import java.sql.Statement; + +/** + * Default wrapper around the Statement + * @author yshao + * + */ +public class StatementWrapper implements Statement { + + private final Statement statement; + + public StatementWrapper(Statement statement) { + this.statement = statement; + } + + @Override + public T unwrap(Class iface) throws SQLException { + if (isWrapperFor(iface)) { + return (T)statement; + } + throw new SQLException("This is not a wrapper of a Statement"); + } + + @Override + public boolean isWrapperFor(Class iface) throws SQLException { + return statement.isWrapperFor(iface); + } + + @Override + public ResultSet executeQuery(String sql) throws SQLException { + return statement.executeQuery(sql); + } + + @Override + public int executeUpdate(String sql) throws SQLException { + return statement.executeUpdate(sql); + } + + @Override + public void close() throws SQLException { + statement.close(); + } + + @Override + public int getMaxFieldSize() throws SQLException { + return statement.getMaxFieldSize(); + } + + @Override + public void setMaxFieldSize(int max) throws SQLException { + statement.setMaxFieldSize(max); + } + + @Override + public int getMaxRows() throws SQLException { + return statement.getMaxRows(); + } + + @Override + public void setMaxRows(int max) throws SQLException { + statement.setMaxRows(max); + } + + @Override + public void setEscapeProcessing(boolean enable) throws SQLException { + statement.setEscapeProcessing(enable); + } + + @Override + public int getQueryTimeout() throws SQLException { + return statement.getQueryTimeout(); + } + + @Override + public void setQueryTimeout(int seconds) throws SQLException { + statement.setQueryTimeout(seconds); + } + + @Override + public void cancel() throws SQLException { + statement.cancel(); + } + + @Override + public SQLWarning getWarnings() throws SQLException { + return statement.getWarnings(); + } + + @Override + public void clearWarnings() throws SQLException { + statement.clearWarnings(); + } + + @Override + public void setCursorName(String name) throws SQLException { + statement.setCursorName(name); + } + + @Override + public boolean execute(String sql) throws SQLException { + return statement.execute(sql); + } + + @Override + public ResultSet getResultSet() throws SQLException { + return statement.getResultSet(); + } + + @Override + public int getUpdateCount() throws SQLException { + return statement.getUpdateCount(); + } + + @Override + public boolean getMoreResults() throws SQLException { + return statement.getMoreResults(); + } + + @Override + public void setFetchDirection(int direction) throws SQLException { + statement.setFetchDirection(direction); + } + + @Override + public int getFetchDirection() throws SQLException { + return statement.getFetchDirection(); + } + + @Override + public void setFetchSize(int rows) throws SQLException { + statement.setFetchSize(rows); + } + + @Override + public int getFetchSize() throws SQLException { + return statement.getFetchSize(); + } + + @Override + public int getResultSetConcurrency() throws SQLException { + return statement.getResultSetConcurrency(); + } + + @Override + public int getResultSetType() throws SQLException { + return statement.getResultSetType(); + } + + @Override + public void addBatch(String sql) throws SQLException { + statement.addBatch(sql); + } + + @Override + public void clearBatch() throws SQLException { + statement.clearBatch(); + } + + @Override + public int[] executeBatch() throws SQLException { + return statement.executeBatch(); + } + + @Override + public Connection getConnection() throws SQLException { + return statement.getConnection(); + } + + @Override + public boolean getMoreResults(int current) throws SQLException { + return statement.getMoreResults(current); + } + + @Override + public ResultSet getGeneratedKeys() throws SQLException { + return statement.getGeneratedKeys(); + } + + @Override + public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { + return statement.executeUpdate(sql, autoGeneratedKeys); + } + + @Override + public int executeUpdate(String sql, int[] columnIndexes) throws SQLException { + return statement.executeUpdate(sql, columnIndexes); + } + + @Override + public int executeUpdate(String sql, String[] columnNames) throws SQLException { + return statement.executeUpdate(sql, columnNames); + } + + @Override + public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { + return statement.execute(sql, autoGeneratedKeys); + } + + @Override + public boolean execute(String sql, int[] columnIndexes) throws SQLException { + return statement.execute(sql, columnIndexes); + } + + @Override + public boolean execute(String sql, String[] columnNames) throws SQLException { + return statement.execute(sql, columnNames); + } + + @Override + public int getResultSetHoldability() throws SQLException { + return statement.getResultSetHoldability(); + } + + @Override + public boolean isClosed() throws SQLException { + return statement.isClosed(); + } + + @Override + public void setPoolable(boolean poolable) throws SQLException { + statement.setPoolable(poolable); + } + + @Override + public boolean isPoolable() throws SQLException { + return statement.isPoolable(); + } + + @Override + public void closeOnCompletion() throws SQLException { + statement.closeOnCompletion(); + } + + @Override + public boolean isCloseOnCompletion() throws SQLException { + return statement.isCloseOnCompletion(); + } +} diff --git a/src/main/java/com/crd/data/wrapper/jtds/CrdJtdsCallableStatement.java b/src/main/java/com/crd/data/wrapper/jtds/CrdJtdsCallableStatement.java new file mode 100644 index 000000000..b24f6255e --- /dev/null +++ b/src/main/java/com/crd/data/wrapper/jtds/CrdJtdsCallableStatement.java @@ -0,0 +1,75 @@ +/* Copyright (c) 2015 + * by Charles River Development, Inc., Burlington, MA + * + * This software is furnished under a license and may be used only in + * accordance with the terms of such license. This software may not be + * provided or otherwise made available to any other party. No title to + * nor ownership of the software is hereby transferred. + * + * This software is the intellectual property of Charles River Development, Inc., + * and is protected by the copyright laws of the United States of America. + * All rights reserved internationally. + * + */ + +package com.crd.data.wrapper.jtds; + +import java.sql.CallableStatement; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.time.Instant; +import java.time.LocalDateTime; + +import com.crd.data.wrapper.CallableStatementWrapper; + +/** + * To provide support for datatime2 + * @author yshao + * + */ +public class CrdJtdsCallableStatement extends CallableStatementWrapper { + + private final Connection conn; + + CrdJtdsCallableStatement(Connection conn, CallableStatement pStatement) { + super(pStatement); + this.conn = conn; + } + + @Override + public ResultSet executeQuery(String sql) throws SQLException { + return new CrdJtdsResultSet(super.executeQuery(sql), this); + } + + @Override + public ResultSet getResultSet() throws SQLException { + return new CrdJtdsResultSet(super.getResultSet(), this); + } + + @Override + public ResultSet executeQuery() throws SQLException { + return new CrdJtdsResultSet(super.executeQuery(), this); + } + + /** + * When the input object x is an Instant or a LocalDateTime, convert to Timestamp and use setString to preserve to the millisecond precision. + * Otherwise, use setObject as is. + */ + @Override + public void setObject(int parameterIndex, Object x) throws SQLException { + if (x instanceof Instant) { + super.setString(parameterIndex, TimestampFormat.format(Timestamp.from((Instant)x))); + } else if (x instanceof LocalDateTime ) { + super.setString(parameterIndex, TimestampFormat.format(Timestamp.valueOf((LocalDateTime)x))); + } else { + super.setObject(parameterIndex, x); + } + } + + @Override + public Connection getConnection() throws SQLException { + return conn; + } +} diff --git a/src/main/java/com/crd/data/wrapper/jtds/CrdJtdsConnection.java b/src/main/java/com/crd/data/wrapper/jtds/CrdJtdsConnection.java new file mode 100644 index 000000000..c462fc42e --- /dev/null +++ b/src/main/java/com/crd/data/wrapper/jtds/CrdJtdsConnection.java @@ -0,0 +1,100 @@ +/* Copyright (c) 2015 + * by Charles River Development, Inc., Burlington, MA + * + * This software is furnished under a license and may be used only in + * accordance with the terms of such license. This software may not be + * provided or otherwise made available to any other party. No title to + * nor ownership of the software is hereby transferred. + * + * This software is the intellectual property of Charles River Development, Inc., + * and is protected by the copyright laws of the United States of America. + * All rights reserved internationally. + * + */ +package com.crd.data.wrapper.jtds; + +import java.sql.CallableStatement; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Statement; + +import com.crd.data.wrapper.ConnectionWrapper; + +/** + * CrdJtdsConnection + * @author yshao + * + */ +public class CrdJtdsConnection extends ConnectionWrapper { + + public CrdJtdsConnection(Connection conn) { + super(conn); + } + + @Override + public Statement createStatement() throws SQLException { + return new CrdJtdsStatement(this, super.createStatement()); + } + + @Override + public PreparedStatement prepareStatement(final String sql)throws SQLException { + return new CrdJtdsPreparedStatement(this, super.prepareStatement(sql)); + } + + @Override + public CallableStatement prepareCall(final String sql) throws SQLException { + return new CrdJtdsCallableStatement(this, super.prepareCall(sql)); + } + + @Override + public DatabaseMetaData getMetaData() throws SQLException { + return new CrdJtdsDatabaseMetaData(this, super.getMetaData()); + } + + @Override + public Statement createStatement(final int resultSetType, final int resultSetConcurrency) throws SQLException { + return new CrdJtdsStatement(this, super.createStatement(resultSetType, resultSetConcurrency)); + } + + @Override + public PreparedStatement prepareStatement(final String sql, final int resultSetType, final int resultSetConcurrency) throws SQLException { + return new CrdJtdsPreparedStatement(this, super.prepareStatement(sql, resultSetType, resultSetConcurrency)); + } + + @Override + public CallableStatement prepareCall(final String sql, final int resultSetType, final int resultSetConcurrency) throws SQLException { + return new CrdJtdsCallableStatement(this, super.prepareCall(sql, resultSetType, resultSetConcurrency)); + } + + @Override + public Statement createStatement(final int resultSetType, final int resultSetConcurrency, final int resultSetHoldability) throws SQLException { + return new CrdJtdsStatement(this, super.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability)); + } + + @Override + public PreparedStatement prepareStatement(final String sql, final int resultSetType, final int resultSetConcurrency, final int resultSetHoldability) throws SQLException { + return new CrdJtdsPreparedStatement(this, super.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability)); + } + + @Override + public CallableStatement prepareCall(final String sql, final int resultSetType, final int resultSetConcurrency, final int resultSetHoldability) throws SQLException { + return new CrdJtdsCallableStatement(this, super.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability)); + } + + @Override + public PreparedStatement prepareStatement(final String sql, final int autoGeneratedKeys) throws SQLException { + return new CrdJtdsPreparedStatement(this, super.prepareStatement(sql, autoGeneratedKeys)); + } + + @Override + public PreparedStatement prepareStatement(final String sql, final int[] columnIndexes) throws SQLException { + return new CrdJtdsPreparedStatement(this, super.prepareStatement(sql, columnIndexes)); + } + + @Override + public PreparedStatement prepareStatement(final String sql, final String[] columnNames) throws SQLException { + return new CrdJtdsPreparedStatement(this, super.prepareStatement(sql, columnNames)); + } +} diff --git a/src/main/java/com/crd/data/wrapper/jtds/CrdJtdsDatabaseMetaData.java b/src/main/java/com/crd/data/wrapper/jtds/CrdJtdsDatabaseMetaData.java new file mode 100644 index 000000000..1efc47f7c --- /dev/null +++ b/src/main/java/com/crd/data/wrapper/jtds/CrdJtdsDatabaseMetaData.java @@ -0,0 +1,127 @@ +/* Copyright (c) 2015 + * by Charles River Development, Inc., Burlington, MA + * + * This software is furnished under a license and may be used only in + * accordance with the terms of such license. This software may not be + * provided or otherwise made available to any other party. No title to + * nor ownership of the software is hereby transferred. + * + * This software is the intellectual property of Charles River Development, Inc., + * and is protected by the copyright laws of the United States of America. + * All rights reserved internationally. + * + */ + +package com.crd.data.wrapper.jtds; + +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; +import java.util.Arrays; +import java.util.List; + +import com.crd.data.wrapper.DatabaseMetaDataWrapper; +import com.crd.data.wrapper.ResultSetWrapper; + +/** + * To provide right metadata for datatime2 + * + * @author yshao + * + */ +public class CrdJtdsDatabaseMetaData extends DatabaseMetaDataWrapper { + + private final Connection conn; + + CrdJtdsDatabaseMetaData(Connection conn, DatabaseMetaData dbMetaData) { + super(dbMetaData); + this.conn = conn; + } + + @Override + public ResultSet getColumns(String catalog, String schemaPattern, + String tableNamePattern, String columnNamePattern) + throws SQLException { + + ResultSet rs = super.getColumns(catalog, schemaPattern, tableNamePattern, columnNamePattern); + return new GetColumnsResultSet(rs); + } + + @Override + public Connection getConnection() throws SQLException { + return conn; + } + + private static class GetColumnsResultSet extends ResultSetWrapper { + + private final static int DATA_TYPE_INDEX = 5; + private final static int TYPE_NAME_INDEX = 6; + private final static int COLUMN_SIZE_INDEX = 7; + private final static int SQL_DATA_TYPE_INDEX = 14; + + private final static String DATETIME = "datetime"; + private final static String DATETIME2 = "datetime2"; + + private final static List INDEXES = Arrays.asList(DATA_TYPE_INDEX, TYPE_NAME_INDEX, COLUMN_SIZE_INDEX, SQL_DATA_TYPE_INDEX); + + private GetColumnsResultSet(ResultSet resultSet) { + super(resultSet); + } + + @Override + public int getInt(int columnIndex) throws SQLException { + + if (!INDEXES.contains(columnIndex)) { + return super.getInt(columnIndex); + } + if (!isDatetime2Column()) { + return super.getInt(columnIndex); + } + if (columnIndex==DATA_TYPE_INDEX) { + return Types.TIMESTAMP; //same as datetime column + } + if (columnIndex==COLUMN_SIZE_INDEX) { + return 23; //same as datetime column + } + if (columnIndex==SQL_DATA_TYPE_INDEX) { + return 9; //same as datetime column + } + throw new SQLException("columnIndex "+columnIndex+" refers to TYPE_NAME which is a String"); + } + + @Override + public String getString(int columnIndex) throws SQLException { + if (!INDEXES.contains(columnIndex)) { + return super.getString(columnIndex); + } + if (!isDatetime2Column()) { + return super.getString(columnIndex); + } + if (columnIndex!=TYPE_NAME_INDEX) { + return ""+getInt(columnIndex); + } + return DATETIME; //same as datetime column + } + + @Override + public Object getObject(int columnIndex) throws SQLException { + if (!INDEXES.contains(columnIndex)) { + return super.getObject(columnIndex); + } + if (!isDatetime2Column()) { + return super.getObject(columnIndex); + } + if (columnIndex!=TYPE_NAME_INDEX) { + return getInt(columnIndex); + } + return DATETIME; //same as datetime column + } + + private boolean isDatetime2Column() throws SQLException { + return DATETIME2.equalsIgnoreCase(super.getString(TYPE_NAME_INDEX)) + && Types.NVARCHAR == super.getInt(SQL_DATA_TYPE_INDEX); + } + } +} diff --git a/src/main/java/com/crd/data/wrapper/jtds/CrdJtdsPreparedStatement.java b/src/main/java/com/crd/data/wrapper/jtds/CrdJtdsPreparedStatement.java new file mode 100644 index 000000000..a52ee2ad9 --- /dev/null +++ b/src/main/java/com/crd/data/wrapper/jtds/CrdJtdsPreparedStatement.java @@ -0,0 +1,80 @@ +/* Copyright (c) 2015 + * by Charles River Development, Inc., Burlington, MA + * + * This software is furnished under a license and may be used only in + * accordance with the terms of such license. This software may not be + * provided or otherwise made available to any other party. No title to + * nor ownership of the software is hereby transferred. + * + * This software is the intellectual property of Charles River Development, Inc., + * and is protected by the copyright laws of the United States of America. + * All rights reserved internationally. + * + */ + +package com.crd.data.wrapper.jtds; + +import java.sql.Connection; +import java.sql.Date; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; + +import com.crd.data.wrapper.PreparedStatementWrapper; + +/** + * To provide support for datatime2 + * @author yshao + * + */ +public class CrdJtdsPreparedStatement extends PreparedStatementWrapper { + + private final Connection conn; + + CrdJtdsPreparedStatement(Connection conn, PreparedStatement pStatement) { + super(pStatement); + this.conn = conn; + } + + @Override + public ResultSet executeQuery(String sql) throws SQLException { + return new CrdJtdsResultSet(super.executeQuery(sql), this); + } + + @Override + public ResultSet getResultSet() throws SQLException { + return new CrdJtdsResultSet(super.getResultSet(), this); + } + + @Override + public ResultSet executeQuery() throws SQLException { + return new CrdJtdsResultSet(super.executeQuery(), this); + } + + /** + * When the input object x is an Instant or a LocalDateTime, convert to Timestamp and use setString to preserve to the millisecond precision. + * Otherwise, use setObject as is. + */ + @Override + public void setObject(int parameterIndex, Object x) throws SQLException { + if (x instanceof Instant) { + super.setString(parameterIndex, TimestampFormat.format(Timestamp.from((Instant)x))); + } else if (x instanceof LocalDateTime ) { + super.setString(parameterIndex, TimestampFormat.format(Timestamp.valueOf((LocalDateTime)x))); + } else if (x instanceof LocalDate) { + super.setObject(parameterIndex, Date.valueOf((LocalDate)x)); + } else { + super.setObject(parameterIndex, x); + } + } + + @Override + public Connection getConnection() throws SQLException { + return conn; + } + +} diff --git a/src/main/java/com/crd/data/wrapper/jtds/CrdJtdsResultSet.java b/src/main/java/com/crd/data/wrapper/jtds/CrdJtdsResultSet.java new file mode 100644 index 000000000..b70e281bf --- /dev/null +++ b/src/main/java/com/crd/data/wrapper/jtds/CrdJtdsResultSet.java @@ -0,0 +1,94 @@ +/* Copyright (c) 2015 + * by Charles River Development, Inc., Burlington, MA + * + * This software is furnished under a license and may be used only in + * accordance with the terms of such license. This software may not be + * provided or otherwise made available to any other party. No title to + * nor ownership of the software is hereby transferred. + * + * This software is the intellectual property of Charles River Development, Inc., + * and is protected by the copyright laws of the United States of America. + * All rights reserved internationally. + * + */ + +package com.crd.data.wrapper.jtds; + +import java.sql.Date; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.sql.Time; +import java.sql.Timestamp; + +import com.crd.data.wrapper.ResultSetWrapper; + +/** + * To provide support for datatime2 + * @author yshao + */ +public class CrdJtdsResultSet extends ResultSetWrapper { + + private final Statement statement; + private final CrdJtdsResultSetMetaData rsMetaData; + + CrdJtdsResultSet(ResultSet resultSet, Statement statement) throws SQLException { + super(resultSet); + this.statement = statement; + rsMetaData = new CrdJtdsResultSetMetaData(resultSet.getMetaData()); + } + + @Override + public ResultSetMetaData getMetaData() throws SQLException { + return rsMetaData; + } + + @Override + public Date getDate(int columnIndex) throws SQLException { + if (!rsMetaData.isDatetime2Column(columnIndex)) { + return super.getDate(columnIndex); + } else { + Timestamp tStamp = super.getTimestamp(columnIndex); + return new Date(tStamp.getTime()); + } + } + + @Override + public Time getTime(int columnIndex) throws SQLException { + if (!rsMetaData.isDatetime2Column(columnIndex)) { + return super.getTime(columnIndex); + } else { + Timestamp tStamp = super.getTimestamp(columnIndex); + return new Time(tStamp.getTime()); + } + } + + @Override + public Date getDate(String columnLabel) throws SQLException { + return getDate(super.findColumn(columnLabel)); + } + + @Override + public Time getTime(String columnLabel) throws SQLException { + return getTime(super.findColumn(columnLabel)); + } + + @Override + public Object getObject(int columnIndex) throws SQLException { + if (!rsMetaData.isDatetime2Column(columnIndex)) { + return super.getObject(columnIndex); + } + return super.getTimestamp(columnIndex); + } + + @Override + public Object getObject(String columnLabel) throws SQLException { + return getObject(super.findColumn(columnLabel)); + } + + @Override + public Statement getStatement() throws SQLException { + return statement; + } +} diff --git a/src/main/java/com/crd/data/wrapper/jtds/CrdJtdsResultSetMetaData.java b/src/main/java/com/crd/data/wrapper/jtds/CrdJtdsResultSetMetaData.java new file mode 100644 index 000000000..1ea037a8d --- /dev/null +++ b/src/main/java/com/crd/data/wrapper/jtds/CrdJtdsResultSetMetaData.java @@ -0,0 +1,96 @@ +/* Copyright (c) 2015 + * by Charles River Development, Inc., Burlington, MA + * + * This software is furnished under a license and may be used only in + * accordance with the terms of such license. This software may not be + * provided or otherwise made available to any other party. No title to + * nor ownership of the software is hereby transferred. + * + * This software is the intellectual property of Charles River Development, Inc., + * and is protected by the copyright laws of the United States of America. + * All rights reserved internationally. + * + */ + +package com.crd.data.wrapper.jtds; + +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Types; + +import com.crd.data.wrapper.ResultSetMetaDataWrapper; + +/** + * To provide right metadata for datatime2 + * + * @author yshao + * + */ +public class CrdJtdsResultSetMetaData extends ResultSetMetaDataWrapper { + + CrdJtdsResultSetMetaData(ResultSetMetaData rsMetaData) throws SQLException { + super(rsMetaData); + datetime2Column = new Boolean[rsMetaData.getColumnCount()+1]; + } + + @Override + public int getColumnType(int column) throws SQLException { + int type = super.getColumnType(column); + if (type != Types.VARCHAR) { + return type; + } + return isDatetime2Column(column) ? Types.TIMESTAMP : type; + } + + @Override + public int getPrecision(int column) throws SQLException { + if (getColumnType(column) == Types.TIMESTAMP) { + return TIME_STAMP_PRECISION; + } else { + return super.getPrecision(column); + } + } + + @Override + public int getScale(int column) throws SQLException { + if (getColumnType(column) == Types.TIMESTAMP) { + return TIME_STAMP_SCALE; + } else { + return super.getScale(column); + } + } + + @Override + public String getColumnClassName(int column) throws SQLException { + if (getColumnType(column) == Types.TIMESTAMP) { + return "java.sql.Timestamp"; + } + return super.getColumnClassName(column); + } + + @Override + public String getColumnTypeName(int column) throws SQLException { + if (getColumnType(column) == Types.TIMESTAMP) { + return "datetime"; + } + return super.getColumnTypeName(column); + } + + boolean isDatetime2Column(int column) throws SQLException { + if (datetime2Column[column] == null) { + boolean isDatetime2 = super.getColumnType(column)==Types.VARCHAR && + DATETIME2_PRECISION == super.getPrecision(column) && + NVARCHAR.equalsIgnoreCase(super.getColumnTypeName(column)); + datetime2Column[column] = isDatetime2; + } + return datetime2Column[column]; + } + + private final Boolean[] datetime2Column; + + private static final String NVARCHAR = "nvarchar"; + private static final int DATETIME2_PRECISION = 26; + + private static final int TIME_STAMP_PRECISION = 23; + private static final int TIME_STAMP_SCALE = 3; +} diff --git a/src/main/java/com/crd/data/wrapper/jtds/CrdJtdsStatement.java b/src/main/java/com/crd/data/wrapper/jtds/CrdJtdsStatement.java new file mode 100644 index 000000000..740e3961d --- /dev/null +++ b/src/main/java/com/crd/data/wrapper/jtds/CrdJtdsStatement.java @@ -0,0 +1,52 @@ +/* Copyright (c) 2015 + * by Charles River Development, Inc., Burlington, MA + * + * This software is furnished under a license and may be used only in + * accordance with the terms of such license. This software may not be + * provided or otherwise made available to any other party. No title to + * nor ownership of the software is hereby transferred. + * + * This software is the intellectual property of Charles River Development, Inc., + * and is protected by the copyright laws of the United States of America. + * All rights reserved internationally. + * + */ + +package com.crd.data.wrapper.jtds; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +import com.crd.data.wrapper.StatementWrapper; + +/** + * To provide support for datatime2 + * @author yshao + * + */ +public class CrdJtdsStatement extends StatementWrapper { + + private final Connection conn; + + CrdJtdsStatement(Connection conn, Statement statement) { + super(statement); + this.conn = conn; + } + + @Override + public ResultSet executeQuery(String sql) throws SQLException { + return new CrdJtdsResultSet(super.executeQuery(sql), this); + } + + @Override + public ResultSet getResultSet() throws SQLException { + return new CrdJtdsResultSet(super.getResultSet(), this); + } + + @Override + public Connection getConnection() throws SQLException { + return conn; + } +} diff --git a/src/main/java/com/crd/data/wrapper/jtds/TimestampFormat.java b/src/main/java/com/crd/data/wrapper/jtds/TimestampFormat.java new file mode 100644 index 000000000..c2b9e28e0 --- /dev/null +++ b/src/main/java/com/crd/data/wrapper/jtds/TimestampFormat.java @@ -0,0 +1,35 @@ +/* Copyright (c) 2015 + * by Charles River Development, Inc., Burlington, MA + * + * This software is furnished under a license and may be used only in + * accordance with the terms of such license. This software may not be + * provided or otherwise made available to any other party. No title to + * nor ownership of the software is hereby transferred. + * + * This software is the intellectual property of Charles River Development, Inc., + * and is protected by the copyright laws of the United States of America. + * All rights reserved internationally. + * + */ + +package com.crd.data.wrapper.jtds; + +import java.sql.Timestamp; +import java.text.SimpleDateFormat; + +/** + * @author yshao + * + */ +class TimestampFormat { + + static final String format(Timestamp tm) { + return timestampFormat.get().format(tm); + } + + private static final ThreadLocal timestampFormat = new ThreadLocal() { + @java.lang.Override protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + } + }; +} diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/issues/Driver.java b/src/test/java/com/microsoft/sqlserver/jdbc/issues/Driver.java index d08ee2ef6..bd2006bfa 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/issues/Driver.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/issues/Driver.java @@ -8,11 +8,7 @@ public class Driver { public static void main(String[] args) throws Exception { log(false, Level.FINEST); - //GH2264.run(); - GH2271.BulkCopyForBatchInsert(true); - //GH2271.BulkCopy(true); - //GH2281.run(); - //GH2283.run(); + GH2534.run(); } private static void log(boolean on, Level lvl){ @@ -25,4 +21,4 @@ private static void log(boolean on, Level lvl){ logger.log(lvl, "The Sql Server logger is correctly configured."); } } -} \ No newline at end of file +} diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/issues/GH2514.java b/src/test/java/com/microsoft/sqlserver/jdbc/issues/GH2514.java new file mode 100644 index 000000000..d850f814e --- /dev/null +++ b/src/test/java/com/microsoft/sqlserver/jdbc/issues/GH2514.java @@ -0,0 +1,13 @@ +package com.microsoft.sqlserver.jdbc.issues; + +import java.sql.*; + +public class GH2514 { + private final static String connectionString = "jdbc:sqlserver://localhost:1433;database=TestDb;user=sa;" + + "password=TestPassword123;encrypt=true;trustServerCertificate=false;"; + static void run() throws SQLException { + try (Connection con = DriverManager.getConnection(connectionString)) { + + } + } +} diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/issues/GH2518.java b/src/test/java/com/microsoft/sqlserver/jdbc/issues/GH2518.java new file mode 100644 index 000000000..26bf3eb85 --- /dev/null +++ b/src/test/java/com/microsoft/sqlserver/jdbc/issues/GH2518.java @@ -0,0 +1,28 @@ +package com.microsoft.sqlserver.jdbc.issues; + +import com.microsoft.sqlserver.jdbc.SQLServerDataSource; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.time.OffsetDateTime; + + +public class GH2518 { + private final static String connectionString = "jdbc:sqlserver://localhost:1433;database=TestDb;user=sa;" + + "password=TestPassword123;encrypt=true;trustServerCertificate=false;"; + static void run() throws SQLException { + final SQLServerDataSource ds = new SQLServerDataSource(); + ds.setURL(connectionString); + ds.setEncrypt("false"); + ds.setUseBulkCopyForBatchInsert(true); + final Connection con = ds.getConnection(); + + final OffsetDateTime odt = OffsetDateTime.now().withSecond(0).withNano(0); + final PreparedStatement ps = con.prepareStatement("insert into dt_bug(dt) values(?)"); + ps.setObject(1, odt); + ps.addBatch(); + ps.executeBatch(); + } +} diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/issues/GH2534.java b/src/test/java/com/microsoft/sqlserver/jdbc/issues/GH2534.java new file mode 100644 index 000000000..fe85a0ac6 --- /dev/null +++ b/src/test/java/com/microsoft/sqlserver/jdbc/issues/GH2534.java @@ -0,0 +1,37 @@ +package com.microsoft.sqlserver.jdbc.issues; + +import com.microsoft.sqlserver.jdbc.SQLServerConnection; +import com.microsoft.sqlserver.jdbc.TestUtils; +import org.junit.jupiter.api.Assertions; + +import java.math.BigDecimal; +import java.sql.*; + + +public class GH2534 { + static void run() throws SQLException { + String connectionString = "jdbc:sqlserver://localhost:1433;databaseName=TestDb;userName=sa;password=TestPassword123;encrypt=false;trustServerCertificate=true"; + try (SQLServerConnection connection = (SQLServerConnection) DriverManager.getConnection(connectionString); Statement stmt = connection.createStatement()) { + TestUtils.dropProcedureIfExists("test_bigdecimal", stmt); + stmt.executeUpdate(""" + create procedure test_bigdecimal + @big_decimal_type decimal(15, 3) , + @big_decimal_type_o decimal(15, 3) output + as begin + set @big_decimal_type_o = @big_decimal_type; + end; + """); + var call = connection.prepareCall(""" + {call test_bigdecimal(100.241, ?)}"""); + int scale = new BigDecimal("100.241").scale(); + call.registerOutParameter(1, Types.DECIMAL, scale); + call.execute(); + + var actual = call.getBigDecimal(1); + + var expected = new BigDecimal("100.241"); + + Assertions.assertEquals(expected, actual); + } + } +} diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/issues/perf/Main.java b/src/test/java/com/microsoft/sqlserver/jdbc/issues/perf/Main.java new file mode 100644 index 000000000..cce263e63 --- /dev/null +++ b/src/test/java/com/microsoft/sqlserver/jdbc/issues/perf/Main.java @@ -0,0 +1,145 @@ +/* Copyright (c) 2022 + * by Charles River Development, Inc., Burlington, MA + * + * This software is furnished under a license and may be used only in + * accordance with the terms of such license. This software may not be + * provided or otherwise made available to any other party. No title to + * nor ownership of the software is hereby transferred. + * + * This software is the intellectual property of Charles River Development, Inc., + * and is protected by the copyright laws of the United States of America. + * All rights reserved internationally. + * + */ +package com.microsoft.sqlserver.jdbc.issues.perf; + +import com.crd.data.wrapper.jtds.CrdJtdsConnection; +//import com.google.common.base.Stopwatch; +import com.microsoft.sqlserver.jdbc.SQLServerResultSet; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * test program for JDBC driver performance comparison + */ +public class Main { + private String driverUrl; + private String userName; + private String password; + private enum DriverType { + jTDS, Microsoft; + int getResultSetType() { + if (this == Microsoft) { + return SQLServerResultSet.TYPE_SS_DIRECT_FORWARD_ONLY; + } + return ResultSet.TYPE_FORWARD_ONLY; + } + } + private DriverType driverType; + + /** + * Usage: {@code Main []} + * @param args program arguments + */ + public static void main(String... args) { + new Main().readArgs(args).runTest(); + } + + public Main readArgs(String[] args) + { + if (args.length < 2) { + System.err.println("Usage: Main []"); + System.exit(2); + return this; + } + driverUrl = args[0]; + userName = args[1]; + if (args.length < 3) { + System.out.println("enter password:"); + password = new String(System.console().readPassword()); + } else { + password = args[2]; + } + driverType = driverUrl.startsWith("jdbc:jtds:sqlserver") ? DriverType.jTDS : DriverType.Microsoft; + return this; + } + private void runTest() + { + System.out.println("------------------------------------------------------------"); + System.out.println(Main.class.getName() + " started at "+ new Date() + " for driver " + driverType); + System.out.println("------------------------------------------------------------"); + //Stopwatch stopwatch = Stopwatch.createStarted(); + long timer = System.currentTimeMillis(); + try { + Map testResults = executeTest(); + printResults(testResults); + } catch (SQLException e) { + System.err.println("Test failed for driver " + driverType + ":" + e.getMessage()); + e.printStackTrace(); + } + + System.out.println("------------------------------------------------------------"); + System.out.println(Main.class.getName() + " finished at "+ new Date() + " for driver " + driverType + " (total elapsed = " + + ((System.currentTimeMillis() - timer)/1000) + " seconds)"); + System.out.println("------------------------------------------------------------"); + } + + private Map executeTest() throws SQLException + { + try (Connection conn = createConnection()) { + PreparePerfTables.preparePerfMultiplier(conn); + PreparePerfTables.preparePerfTable(conn); + int testNumber = 0; + List tests = getTests(); + Map testResults = new LinkedHashMap<>(); + for (PerformanceTest test : tests) { + testNumber++; + System.out.println("running " + test.getDescription() + "... (" + testNumber + "/" + tests.size() + ")"); + PerformanceTest.PerformanceResult result = test.run(conn, driverType.getResultSetType()); + testResults.put(test.getDescription(), result); + } + return testResults; + } + } + + private List getTests() + { + return List.of( + new PerfTablePerformanceTest(0), + new PerfTablePerformanceTest(512) + ); + } + + public Connection createConnection() throws SQLException { + Connection conn = DriverManager.getConnection(driverUrl, userName, password); + if (DriverType.jTDS == driverType) { + // for jTDS we need to wrap the connection in order to adjust some of the return types like timestamps + return new CrdJtdsConnection(conn); + } + return conn; + } + private void printResults(Map testResults) + { + System.out.println(); + System.out.printf("T# %-75s%-15s%-13s%-15s%-15s%-12s%-6s%n", "Performance Test", "Result Count", "Time(ms)", "Size", "nullCount", "columnCount", "fsize"); + int index = 1; + for (Map.Entry entry : testResults.entrySet()) { + int length = entry.getKey().length(); + String description = entry.getKey().substring(0, Math.min(60, length))+"....."; + PerformanceTest.PerformanceResult result = entry.getValue(); + System.out.printf("%2d %-75s%-15s%-13s%-15s%-15s%-12s%-6s%n", index, description, + result.numberOfRecords(), result.elapsedMilliseconds(), result.totalBytes(), + result.nullColumnCount(), result.columnCount(), result.rsFetchSize()); + index++; + } + System.out.println(); + } +} diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/issues/perf/PerfTablePerformanceTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/issues/perf/PerfTablePerformanceTest.java new file mode 100644 index 000000000..f483f0cee --- /dev/null +++ b/src/test/java/com/microsoft/sqlserver/jdbc/issues/perf/PerfTablePerformanceTest.java @@ -0,0 +1,106 @@ +package com.microsoft.sqlserver.jdbc.issues.perf; + +//import com.google.common.base.Stopwatch; + +import java.math.BigDecimal; +import java.sql.*; +import java.util.concurrent.TimeUnit; + +public class PerfTablePerformanceTest implements PerformanceTest +{ + private final int fetchSize; + public PerfTablePerformanceTest(int fetchSize) + { + this.fetchSize = fetchSize; + } + + public String getName() + { + return "PERF_TABLE(" + fetchSize + ")"; + } + + @Override + public String getDescription() { + return "SELECT * FROM PERF_TABLE(" + (fetchSize == 0 ? "default" : String.valueOf(fetchSize)) + ")"; + } + + @Override + public PerformanceResult run(Connection conn, int resultSetType) throws SQLException + { + long timer = System.currentTimeMillis(); + //Stopwatch stopwatch = Stopwatch.createStarted(); + int numberOfRecords = 0; + long totalBytes = 0L; + int nullColumnCount = 0; + int columns = 0; + int rsFetchSize = 0; + try (Statement stmt = conn.createStatement(resultSetType, ResultSet.CONCUR_READ_ONLY)) { + if (fetchSize != 0) { + int stmtFetchSize = stmt.getFetchSize(); + if (fetchSize != stmtFetchSize) { + stmt.setFetchSize(fetchSize); + System.out.println("Changed stmt.fetchSize from " + stmtFetchSize + " to " + fetchSize); + } + } + String sql = "SELECT T.* FROM [dbo].[PERF_TABLE] T CROSS JOIN [dbo].[PERF_MULTIPLIER] M WHERE M.ID <= 1000"; + try (ResultSet rs = stmt.executeQuery(sql)) { + rsFetchSize = rs.getFetchSize(); + if (fetchSize != 0 && fetchSize != rsFetchSize) { + rs.setFetchSize(fetchSize); + System.out.println("Changed rs.fetchSize from " + rsFetchSize + " to " + fetchSize); + rsFetchSize = fetchSize; + } + columns = rs.getMetaData().getColumnCount(); + while (rs.next()) { + numberOfRecords++; + int columnIndex = 1; + int id = rs.getInt(columnIndex++); + totalBytes += 4; + for (int repeat = 0; repeat < PreparePerfTables.COLUMN_REPEAT_COUNT; repeat++) { + String indicatorValue = rs.getString(columnIndex++); + if (indicatorValue == null) { + nullColumnCount++; + } else { + totalBytes += 1; + } + String stringValue = rs.getString(columnIndex++); + if (stringValue == null) { + nullColumnCount++; + } else { + totalBytes += stringValue.length(); + } + long longValue = rs.getLong(columnIndex++); + if (rs.wasNull()) { + longValue = Long.MIN_VALUE; + nullColumnCount++; + } else { + totalBytes += 8; + } + double doubleValue = rs.getDouble(columnIndex++); + if (rs.wasNull()) { + doubleValue = Double.NaN; + nullColumnCount++; + } else { + totalBytes += 8; + } + BigDecimal decimalValue = rs.getBigDecimal(columnIndex++); + if (decimalValue == null) { + nullColumnCount++; + } else { + totalBytes += 12; + } + Timestamp timestampValue = rs.getTimestamp(columnIndex++); + if (timestampValue == null) { + nullColumnCount++; + } else { + totalBytes += 12; + } + } + } + } + } + final long elapsed = System.currentTimeMillis() - timer; + System.out.println("Retrieved " + numberOfRecords + " rows in " + elapsed + " ms."); + return new PerformanceResult(elapsed, numberOfRecords, totalBytes, nullColumnCount, columns, rsFetchSize); + } +} diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/issues/perf/PerformanceTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/issues/perf/PerformanceTest.java new file mode 100644 index 000000000..fa429892c --- /dev/null +++ b/src/test/java/com/microsoft/sqlserver/jdbc/issues/perf/PerformanceTest.java @@ -0,0 +1,32 @@ +package com.microsoft.sqlserver.jdbc.issues.perf; + +import java.sql.Connection; +import java.sql.SQLException; + +/** + * Test jdbc driver's performance + */ +public interface PerformanceTest +{ + + /** + * @return -- the name of the test + */ + String getName(); + + /** + * @return -- the description of the test + */ + String getDescription(); + + /** + * run the test + * @param conn connection + * @param resultSetType result set type + * @return -- the first captures execution time, while the second is result count + * @throws SQLException if an error occurs + */ + PerformanceResult run(Connection conn, int resultSetType) throws SQLException; + + record PerformanceResult(long elapsedMilliseconds, int numberOfRecords, long totalBytes, int nullColumnCount, int columnCount, int rsFetchSize) {} +} diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/issues/perf/PreparePerfTables.java b/src/test/java/com/microsoft/sqlserver/jdbc/issues/perf/PreparePerfTables.java new file mode 100644 index 000000000..2f192cfa5 --- /dev/null +++ b/src/test/java/com/microsoft/sqlserver/jdbc/issues/perf/PreparePerfTables.java @@ -0,0 +1,148 @@ +package com.microsoft.sqlserver.jdbc.issues.perf; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.sql.*; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +/** + * Prepare PERF_MULTIPLIER, and PERF_TABLE + */ +public class PreparePerfTables +{ + private final static int MUTLIPLIER_MAX = 819_200; + + private final static String SELECT_PERF_MULTIPLIER_COUNT = "IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[PERF_MULTIPLIER]')) SELECT COUNT(*) FROM [dbo].[PERF_MULTIPLIER] ELSE SELECT 0"; + private final static String INSERT_INTO_PERF_MULTIPLIER = "INSERT INTO [dbo].[PERF_MULTIPLIER] VALUES (?)"; + private final static String INSERT_INTO_PERF_MULTIPLIER_SELECT_ADD = "INSERT INTO [dbo].[PERF_MULTIPLIER] SELECT ID + ? FROM [dbo].[PERF_MULTIPLIER]"; + private final static String INSERT_INTO_PERF_MULTIPLIER_SELECT_MULTIPLY = "INSERT INTO [dbo].[PERF_MULTIPLIER] SELECT ID * ? + ? FROM PERF_MULTIPLIER"; + private final static String DROP_PERF_MULTIPLIER = "DROP TABLE IF EXISTS [dbo].[PERF_MULTIPLIER]"; + private final static String CREATE_PERF_MULTIPLIER = "CREATE TABLE [dbo].[PERF_MULTIPLIER] ( ID int NOT NULL PRIMARY KEY )"; + + final static int COLUMN_REPEAT_COUNT = 100; + private final static int ROW_COUNT = 500; + + private final static String SELECT_PERF_TABLE_COUNT = "IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[PERF_TABLE]')) SELECT COUNT(*) FROM [dbo].[PERF_TABLE] ELSE SELECT 0"; + private final static String DROP_PERF_TABLE = "DROP TABLE IF EXISTS [dbo].[PERF_TABLE]"; + private final static String CREATE_PERF_TABLE + = "CREATE TABLE [dbo].[PERF_TABLE](\n" + + " [ID] int NOT NULL PRIMARY KEY,\n"; + + private final static String INSERT_INTO_PERF_TABLE = "INSERT INTO [dbo].[PERF_TABLE] VALUES (?"; +// private final static Column[] columns = new Column[] {null, null, StringColumn, IntegerColumn, LongColumn, BigDecimalColumn, BigDecimalColumn, DoubleColumn, TimestampColumn}; +// +// private final static String DROP_PERF_TABLE_WITH_LOBS = "DROP TABLE [dbo].[PERF_TABLE_WITH_LOBS]"; +// private final static String CREATE_PERF_TABLE_WITH_LOBS +// = "CREATE TABLE [dbo].[PERF_TABLE_WITH_LOBS](\n" +// + " [ID] [decimal](18, 0) NOT NULL PRIMARY KEY,\n" +// + " [COL_STRING] [varchar](64) NULL,\n" +// + " [COL_INT] [decimal](9, 0) NULL,\n" +// + " [COL_LONG] [decimal](18, 0) NULL,\n" +// + " [COL_DECIMAL] [decimal](18, 4) NULL,\n" +// + " [COL_DOUBLE] [float] NULL,\n" +// + " [COL_TIMESTAMP] [datetime] NULL,\n" +// + " [COL_BLOB] [varbinary](max) NULL,\n" +// + " [COL_CLOB] [varchar](max) NULL,\n" +// + ")"; +// +// private final static String INSERT_INTO_PERF_TABLE_WITH_LOBS = "INSERT INTO PERF_TABLE_WITH_LOBS VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; +// private final static Column[] columnsWithLobs = new Column[] {null, null, StringColumn, IntegerColumn, LongColumn, BigDecimalColumn, DoubleColumn, TimestampColumn, BlobColumn, ClobColumn}; + + public static void preparePerfMultiplier(Connection conn) throws SQLException + { + try (PreparedStatement pstmt = conn.prepareStatement(SELECT_PERF_MULTIPLIER_COUNT); ResultSet rs = pstmt.executeQuery()) { + while(rs.next()) { + if (rs.getInt(1) == MUTLIPLIER_MAX) { + System.out.println("PERF_MULTIPLIER table already created."); + return; + } + } + } + System.out.println("prepare PERF_MULTIPLIER table......"); + + try(Statement stmt = conn.createStatement()) { + stmt.execute(DROP_PERF_MULTIPLIER); + } + + try (Statement stmt = conn.createStatement()) { + stmt.execute(CREATE_PERF_MULTIPLIER); + } + try (PreparedStatement pstmt = conn.prepareStatement(INSERT_INTO_PERF_MULTIPLIER)) { + for (int i = 1; i <= 100; i++) { + pstmt.setInt(1, i); + pstmt.addBatch(); + } + pstmt.executeBatch(); + } + try (PreparedStatement pstmt = conn.prepareStatement(INSERT_INTO_PERF_MULTIPLIER_SELECT_ADD)) { + for (int i = 100; i < MUTLIPLIER_MAX; i *= 2) { + pstmt.setInt(1, i); + pstmt.execute(); + } + } + } + + public static void preparePerfTable(Connection conn) throws SQLException + { + try (PreparedStatement pstmt = conn.prepareStatement(SELECT_PERF_TABLE_COUNT); ResultSet rs = pstmt.executeQuery()) { + while(rs.next()) { + if (rs.getInt(1) == ROW_COUNT) { + System.out.println("PERF_TABLE table already created."); + return; + } + } + } + System.out.println("prepare PERF_TABLE table......"); + + try(Statement stmt = conn.createStatement()) { + stmt.execute(DROP_PERF_TABLE); + } + StringBuilder createTablelSql = new StringBuilder(CREATE_PERF_TABLE); + StringBuilder insertSql = new StringBuilder(INSERT_INTO_PERF_TABLE); + for (int i = 1; i <= COLUMN_REPEAT_COUNT; i++) { + createTablelSql.append("[COL_IND_").append(i).append("] char(1) NULL,\n"); + createTablelSql.append("[COL_STRING_").append(i).append("] varchar(64) NULL,\n"); + createTablelSql.append("[COL_LONG_").append(i).append("] decimal(18,0) NULL,\n"); + createTablelSql.append("[COL_FLOAT_").append(i).append("] float NULL,\n"); + createTablelSql.append("[COL_DECIMAL_").append(i).append("] decimal(25,4) NULL,\n"); + createTablelSql.append("[COL_TIMESTAMP_").append(i).append("] datetime NULL,\n"); + insertSql.append(",?,?,?,?,?,?"); + } + createTablelSql.append(")"); + insertSql.append(")"); + try (Statement stmt = conn.createStatement()) { + stmt.execute(createTablelSql.toString()); + } + ThreadLocalRandom random = ThreadLocalRandom.current(); + long timeEnd = System.currentTimeMillis(); + long timeStart = timeEnd - 365 * 86400; + try (PreparedStatement stmt = conn.prepareStatement(insertSql.toString())) { + for (int rowIndex = 0; rowIndex < ROW_COUNT; rowIndex++) { + stmt.setInt(1, rowIndex + 1); + int columnIndex = 2; + for (int i = 1; i <= COLUMN_REPEAT_COUNT; i++) { + boolean nulls = random.nextBoolean(); + if (true) { + stmt.setString(columnIndex++, null); + stmt.setString(columnIndex++, null); + stmt.setNull(columnIndex++, Types.BIGINT); + stmt.setNull(columnIndex++, Types.FLOAT); + stmt.setBigDecimal(columnIndex++, null); + stmt.setTimestamp(columnIndex++, null); + } else { + stmt.setString(columnIndex++, random.nextBoolean() ? "Y" : "N"); + stmt.setString(columnIndex++, UUID.randomUUID().toString()); + stmt.setLong(columnIndex++, random.nextLong(1, 1_000_000_000_000L)); + final double doubleValue = random.nextDouble(1.0d, 1_000_000_000.0d); + stmt.setDouble(columnIndex++, doubleValue); + stmt.setBigDecimal(columnIndex++, BigDecimal.valueOf(doubleValue).setScale(4, RoundingMode.HALF_UP)); + stmt.setTimestamp(columnIndex++, new Timestamp(random.nextLong(timeStart, timeEnd))); + } + } + stmt.execute(); + } + } + } +} +