result filter && tenant support

This commit is contained in:
kiki
2014-01-10 17:47:30 +08:00
parent f0bbca5e9e
commit 1f59bba007
24 changed files with 1589 additions and 185 deletions
+1 -1
View File
@@ -19,7 +19,7 @@ public final class VERSION {
public final static int MajorVersion = 1;
public final static int MinorVersion = 0;
public final static int RevisionVersion = 1;
public final static int RevisionVersion = 2;
public static String getVersionNumber() {
return VERSION.MajorVersion + "." + VERSION.MinorVersion + "." + VERSION.RevisionVersion;
@@ -61,9 +61,9 @@ import com.alibaba.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;
import com.alibaba.druid.util.DruidPasswordCallback;
import com.alibaba.druid.util.Histogram;
import com.alibaba.druid.util.Utils;
import com.alibaba.druid.util.JdbcUtils;
import com.alibaba.druid.util.StringUtils;
import com.alibaba.druid.util.Utils;
/**
* @author wenshao<szujobs@hotmail.com>
@@ -1314,6 +1314,7 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
protected final AtomicLong statementIdSeed = new AtomicLong(20000);
protected final AtomicLong resultSetIdSeed = new AtomicLong(50000);
protected final AtomicLong transactionIdSeed = new AtomicLong(60000);
protected final AtomicLong metaDataIdSeed = new AtomicLong(80000);
public long createConnectionId() {
return connectionIdSeed.incrementAndGet();
@@ -1323,6 +1324,10 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
return statementIdSeed.getAndIncrement();
}
public long createMetaDataId() {
return metaDataIdSeed.getAndIncrement();
}
public long createResultSetId() {
return resultSetIdSeed.getAndIncrement();
}
@@ -47,6 +47,8 @@ public interface DataSourceProxy {
long createResultSetId();
long createMetaDataId();
long createTransactionId();
Properties getConnectProperties();
@@ -35,8 +35,8 @@ import com.alibaba.druid.filter.FilterChain;
import com.alibaba.druid.filter.FilterChainImpl;
import com.alibaba.druid.stat.JdbcDataSourceStat;
import com.alibaba.druid.stat.JdbcStatManager;
import com.alibaba.druid.util.Utils;
import com.alibaba.druid.util.JdbcUtils;
import com.alibaba.druid.util.Utils;
/**
* @author wenshao<szujobs@hotmail.com>
@@ -58,6 +58,7 @@ public class DataSourceProxyImpl implements DataSourceProxy, DataSourceProxyImpl
private final AtomicLong connectionIdSeed = new AtomicLong(10000);
private final AtomicLong statementIdSeed = new AtomicLong(20000);
private final AtomicLong resultSetIdSeed = new AtomicLong(50000);
private final AtomicLong metaDataIdSeed = new AtomicLong(100000);
private final AtomicLong transactionIdSeed = new AtomicLong(0);
private final JdbcDataSourceStat dataSourceStat;
@@ -364,6 +365,10 @@ public class DataSourceProxyImpl implements DataSourceProxy, DataSourceProxyImpl
return resultSetIdSeed.getAndIncrement();
}
public long createMetaDataId() {
return metaDataIdSeed.getAndIncrement();
}
@Override
public long createTransactionId() {
return transactionIdSeed.getAndIncrement();
@@ -0,0 +1,28 @@
/*
* Copyright 1999-2011 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.proxy.jdbc;
import java.sql.ResultSetMetaData;
/**
* @author kiki
*/
public interface ResultSetMetaDataProxy extends ResultSetMetaData, WrapperProxy {
ResultSetMetaData getResultSetMetaDataRaw();
}
@@ -0,0 +1,154 @@
/*
* Copyright 1999-2011 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.druid.proxy.jdbc;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import com.alibaba.druid.filter.FilterChain;
/**
* @author kiki
*/
public class ResultSetMetaDataProxyImpl extends WrapperProxyImpl implements ResultSetMetaDataProxy {
private final ResultSetMetaData metaData;
private final ResultSetProxy resultSetProxy;
public ResultSetMetaDataProxyImpl(ResultSetMetaData metaData, long id, ResultSetProxy resultSetProxy){
super(metaData, id);
this.metaData = metaData;
this.resultSetProxy = resultSetProxy;
}
@Override
public int getColumnCount() throws SQLException {
return metaData.getColumnCount() - resultSetProxy.getHiddenColumnCount();
}
@Override
public boolean isAutoIncrement(int column) throws SQLException {
return metaData.isAutoIncrement(resultSetProxy.getPhysicalColumn(column));
}
@Override
public boolean isCaseSensitive(int column) throws SQLException {
return metaData.isCaseSensitive(resultSetProxy.getPhysicalColumn(column));
}
@Override
public boolean isSearchable(int column) throws SQLException {
return metaData.isSearchable(resultSetProxy.getPhysicalColumn(column));
}
@Override
public boolean isCurrency(int column) throws SQLException {
return metaData.isCurrency(resultSetProxy.getPhysicalColumn(column));
}
@Override
public int isNullable(int column) throws SQLException {
return metaData.isNullable(resultSetProxy.getPhysicalColumn(column));
}
@Override
public boolean isSigned(int column) throws SQLException {
return metaData.isSigned(resultSetProxy.getPhysicalColumn(column));
}
@Override
public int getColumnDisplaySize(int column) throws SQLException {
return metaData.getColumnDisplaySize(resultSetProxy.getPhysicalColumn(column));
}
@Override
public String getColumnLabel(int column) throws SQLException {
return metaData.getColumnLabel(resultSetProxy.getPhysicalColumn(column));
}
@Override
public String getColumnName(int column) throws SQLException {
return metaData.getColumnName(resultSetProxy.getPhysicalColumn(column));
}
@Override
public String getSchemaName(int column) throws SQLException {
return metaData.getSchemaName(resultSetProxy.getPhysicalColumn(column));
}
@Override
public int getPrecision(int column) throws SQLException {
return metaData.getPrecision(resultSetProxy.getPhysicalColumn(column));
}
@Override
public int getScale(int column) throws SQLException {
return metaData.getScale(resultSetProxy.getPhysicalColumn(column));
}
@Override
public String getTableName(int column) throws SQLException {
return metaData.getTableName(resultSetProxy.getPhysicalColumn(column));
}
@Override
public String getCatalogName(int column) throws SQLException {
return metaData.getCatalogName(resultSetProxy.getPhysicalColumn(column));
}
@Override
public int getColumnType(int column) throws SQLException {
return metaData.getColumnType(resultSetProxy.getPhysicalColumn(column));
}
@Override
public String getColumnTypeName(int column) throws SQLException {
return metaData.getColumnTypeName(resultSetProxy.getPhysicalColumn(column));
}
@Override
public boolean isReadOnly(int column) throws SQLException {
return metaData.isReadOnly(resultSetProxy.getPhysicalColumn(column));
}
@Override
public boolean isWritable(int column) throws SQLException {
return metaData.isWritable(resultSetProxy.getPhysicalColumn(column));
}
@Override
public boolean isDefinitelyWritable(int column) throws SQLException {
return metaData.isDefinitelyWritable(resultSetProxy.getPhysicalColumn(column));
}
@Override
public String getColumnClassName(int column) throws SQLException {
return metaData.getColumnClassName(resultSetProxy.getPhysicalColumn(column));
}
@Override
public ResultSetMetaData getResultSetMetaDataRaw() {
return metaData;
}
@Override
public FilterChain createChain() {
return null;
}
}
@@ -16,6 +16,8 @@
package com.alibaba.druid.proxy.jdbc;
import java.sql.ResultSet;
import java.util.List;
import java.util.Map;
import com.alibaba.druid.stat.JdbcSqlStat;
@@ -29,7 +31,7 @@ public interface ResultSetProxy extends ResultSet, WrapperProxy {
StatementProxy getStatementProxy();
String getSql();
JdbcSqlStat getSqlStat();
int getCursorIndex();
@@ -41,22 +43,35 @@ public interface ResultSetProxy extends ResultSet, WrapperProxy {
void setConstructNano(long constructNano);
void setConstructNano();
int getCloseCount();
void addReadStringLength(int length);
long getReadStringLength();
void addReadBytesLength(int length);
long getReadBytesLength();
void incrementOpenInputStreamCount();
int getOpenInputStreamCount();
void incrementOpenReaderCount();
int getOpenReaderCount();
int getPhysicalColumn(int logicColumn);
List<Integer> getHiddenColumns();
int getHiddenColumnCount();
void setLogicColumnMap(Map<Integer, Integer> logicColumnMap);
void setPhysicalColumnMap(Map<Integer, Integer> physicalColumnMap);
void setHiddenColumns(List<Integer> hiddenColumns);
}
@@ -36,6 +36,7 @@ import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import com.alibaba.druid.filter.FilterChainImpl;
@@ -46,23 +47,27 @@ import com.alibaba.druid.stat.JdbcSqlStat;
*/
public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetProxy {
private final ResultSet resultSet;
private final StatementProxy statement;
private final String sql;
private final ResultSet resultSet;
private final StatementProxy statement;
private final String sql;
protected int cursorIndex = 0;
protected int fetchRowCount = 0;
protected long constructNano;
protected final JdbcSqlStat sqlStat;
private int closeCount = 0;
protected int cursorIndex = 0;
protected int fetchRowCount = 0;
protected long constructNano;
protected final JdbcSqlStat sqlStat;
private int closeCount = 0;
private long readStringLength = 0;
private long readBytesLength = 0;
private long readStringLength = 0;
private long readBytesLength = 0;
private int openInputStreamCount = 0;
private int openReaderCount = 0;
private int openInputStreamCount = 0;
private int openReaderCount = 0;
private FilterChainImpl filterChain = null;
private Map<Integer, Integer> logicColumnMap = null;
private Map<Integer, Integer> physicalColumnMap = null;
private List<Integer> hiddenColumns = null;
private FilterChainImpl filterChain = null;
public ResultSetProxyImpl(StatementProxy statement, ResultSet resultSet, long id, String sql){
super(resultSet, id);
@@ -117,10 +122,10 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
} else {
this.filterChain = null;
}
return chain;
}
public void recycleFilterChain(FilterChainImpl chain) {
chain.reset();
this.filterChain = chain;
@@ -180,9 +185,10 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public int findColumn(String columnLabel) throws SQLException {
FilterChainImpl chain = createChain();
int value = chain.resultSet_findColumn(this, columnLabel);
int physicalColumn = chain.resultSet_findColumn(this, columnLabel);
recycleFilterChain(chain);
return value;
return getLogicColumn(physicalColumn);
}
@Override
@@ -196,7 +202,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public Array getArray(int columnIndex) throws SQLException {
FilterChainImpl chain = createChain();
Array value = chain.resultSet_getArray(this, columnIndex);
Array value = chain.resultSet_getArray(this, getPhysicalColumn(columnIndex));
recycleFilterChain(chain);
return value;
}
@@ -212,7 +218,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public InputStream getAsciiStream(int columnIndex) throws SQLException {
FilterChainImpl chain = createChain();
InputStream value = chain.resultSet_getAsciiStream(this, columnIndex);
InputStream value = chain.resultSet_getAsciiStream(this, getPhysicalColumn(columnIndex));
recycleFilterChain(chain);
return value;
}
@@ -228,7 +234,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
FilterChainImpl chain = createChain();
BigDecimal value = chain.resultSet_getBigDecimal(this, columnIndex);
BigDecimal value = chain.resultSet_getBigDecimal(this, getPhysicalColumn(columnIndex));
recycleFilterChain(chain);
return value;
}
@@ -244,7 +250,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {
FilterChainImpl chain = createChain();
BigDecimal value = chain.resultSet_getBigDecimal(this, columnIndex, scale);
BigDecimal value = chain.resultSet_getBigDecimal(this, getPhysicalColumn(columnIndex), scale);
recycleFilterChain(chain);
return value;
}
@@ -260,7 +266,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public InputStream getBinaryStream(int columnIndex) throws SQLException {
FilterChainImpl chain = createChain();
InputStream value = chain.resultSet_getBinaryStream(this, columnIndex);
InputStream value = chain.resultSet_getBinaryStream(this, getPhysicalColumn(columnIndex));
recycleFilterChain(chain);
return value;
}
@@ -276,7 +282,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public Blob getBlob(int columnIndex) throws SQLException {
FilterChainImpl chain = createChain();
Blob value = chain.resultSet_getBlob(this, columnIndex);
Blob value = chain.resultSet_getBlob(this, getPhysicalColumn(columnIndex));
recycleFilterChain(chain);
return value;
}
@@ -292,7 +298,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public boolean getBoolean(int columnIndex) throws SQLException {
FilterChainImpl chain = createChain();
boolean value = chain.resultSet_getBoolean(this, columnIndex);
boolean value = chain.resultSet_getBoolean(this, getPhysicalColumn(columnIndex));
recycleFilterChain(chain);
return value;
}
@@ -308,7 +314,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public byte getByte(int columnIndex) throws SQLException {
FilterChainImpl chain = createChain();
byte value = chain.resultSet_getByte(this, columnIndex);
byte value = chain.resultSet_getByte(this, getPhysicalColumn(columnIndex));
recycleFilterChain(chain);
return value;
}
@@ -324,7 +330,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public byte[] getBytes(int columnIndex) throws SQLException {
FilterChainImpl chain = createChain();
byte[] value = chain.resultSet_getBytes(this, columnIndex);
byte[] value = chain.resultSet_getBytes(this, getPhysicalColumn(columnIndex));
recycleFilterChain(chain);
return value;
}
@@ -340,7 +346,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public Reader getCharacterStream(int columnIndex) throws SQLException {
FilterChainImpl chain = createChain();
Reader value = chain.resultSet_getCharacterStream(this, columnIndex);
Reader value = chain.resultSet_getCharacterStream(this, getPhysicalColumn(columnIndex));
recycleFilterChain(chain);
return value;
}
@@ -356,7 +362,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public Clob getClob(int columnIndex) throws SQLException {
FilterChainImpl chain = createChain();
Clob value = chain.resultSet_getClob(this, columnIndex);
Clob value = chain.resultSet_getClob(this, getPhysicalColumn(columnIndex));
recycleFilterChain(chain);
return value;
}
@@ -388,7 +394,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public Date getDate(int columnIndex) throws SQLException {
FilterChainImpl chain = createChain();
Date value = chain.resultSet_getDate(this, columnIndex);
Date value = chain.resultSet_getDate(this, getPhysicalColumn(columnIndex));
recycleFilterChain(chain);
return value;
}
@@ -404,7 +410,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public Date getDate(int columnIndex, Calendar cal) throws SQLException {
FilterChainImpl chain = createChain();
Date value = chain.resultSet_getDate(this, columnIndex, cal);
Date value = chain.resultSet_getDate(this, getPhysicalColumn(columnIndex), cal);
recycleFilterChain(chain);
return value;
}
@@ -420,7 +426,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public double getDouble(int columnIndex) throws SQLException {
FilterChainImpl chain = createChain();
double value = chain.resultSet_getDouble(this, columnIndex);
double value = chain.resultSet_getDouble(this, getPhysicalColumn(columnIndex));
recycleFilterChain(chain);
return value;
}
@@ -444,7 +450,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public int getFetchSize() throws SQLException {
FilterChainImpl chain = createChain();
int value = chain.resultSet_getFetchSize(this);
int value = chain.resultSet_getFetchSize(this);
recycleFilterChain(chain);
return value;
}
@@ -452,7 +458,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public float getFloat(int columnIndex) throws SQLException {
FilterChainImpl chain = createChain();
float value = chain.resultSet_getFloat(this, columnIndex);
float value = chain.resultSet_getFloat(this, getPhysicalColumn(columnIndex));
recycleFilterChain(chain);
return value;
}
@@ -476,7 +482,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public int getInt(int columnIndex) throws SQLException {
FilterChainImpl chain = createChain();
int value = chain.resultSet_getInt(this, columnIndex);
int value = chain.resultSet_getInt(this, getPhysicalColumn(columnIndex));
recycleFilterChain(chain);
return value;
}
@@ -492,7 +498,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public long getLong(int columnIndex) throws SQLException {
FilterChainImpl chain = createChain();
long value = chain.resultSet_getLong(this, columnIndex);
long value = chain.resultSet_getLong(this, getPhysicalColumn(columnIndex));
recycleFilterChain(chain);
return value;
}
@@ -516,7 +522,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public Reader getNCharacterStream(int columnIndex) throws SQLException {
FilterChainImpl chain = createChain();
Reader value = chain.resultSet_getNCharacterStream(this, columnIndex);
Reader value = chain.resultSet_getNCharacterStream(this, getPhysicalColumn(columnIndex));
recycleFilterChain(chain);
return value;
}
@@ -532,7 +538,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public NClob getNClob(int columnIndex) throws SQLException {
FilterChainImpl chain = createChain();
NClob value = chain.resultSet_getNClob(this, columnIndex);
NClob value = chain.resultSet_getNClob(this, getPhysicalColumn(columnIndex));
recycleFilterChain(chain);
return value;
}
@@ -548,7 +554,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public String getNString(int columnIndex) throws SQLException {
FilterChainImpl chain = createChain();
String value = chain.resultSet_getNString(this, columnIndex);
String value = chain.resultSet_getNString(this, getPhysicalColumn(columnIndex));
recycleFilterChain(chain);
return value;
}
@@ -564,7 +570,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public Object getObject(int columnIndex) throws SQLException {
FilterChainImpl chain = createChain();
Object value = chain.resultSet_getObject(this, columnIndex);
Object value = chain.resultSet_getObject(this, getPhysicalColumn(columnIndex));
recycleFilterChain(chain);
return value;
}
@@ -580,7 +586,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public Object getObject(int columnIndex, Map<String, Class<?>> map) throws SQLException {
FilterChainImpl chain = createChain();
Object value = chain.resultSet_getObject(this, columnIndex, map);
Object value = chain.resultSet_getObject(this, getPhysicalColumn(columnIndex), map);
recycleFilterChain(chain);
return value;
}
@@ -596,7 +602,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public Ref getRef(int columnIndex) throws SQLException {
FilterChainImpl chain = createChain();
Ref value = chain.resultSet_getRef(this, columnIndex);
Ref value = chain.resultSet_getRef(this, getPhysicalColumn(columnIndex));
recycleFilterChain(chain);
return value;
}
@@ -620,7 +626,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public RowId getRowId(int columnIndex) throws SQLException {
FilterChainImpl chain = createChain();
RowId value = chain.resultSet_getRowId(this, columnIndex);
RowId value = chain.resultSet_getRowId(this, getPhysicalColumn(columnIndex));
recycleFilterChain(chain);
return value;
}
@@ -636,7 +642,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public SQLXML getSQLXML(int columnIndex) throws SQLException {
FilterChainImpl chain = createChain();
SQLXML value = chain.resultSet_getSQLXML(this, columnIndex);
SQLXML value = chain.resultSet_getSQLXML(this, getPhysicalColumn(columnIndex));
recycleFilterChain(chain);
return value;
}
@@ -652,7 +658,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public short getShort(int columnIndex) throws SQLException {
FilterChainImpl chain = createChain();
short value = chain.resultSet_getShort(this, columnIndex);
short value = chain.resultSet_getShort(this, getPhysicalColumn(columnIndex));
recycleFilterChain(chain);
return value;
}
@@ -676,7 +682,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public String getString(int columnIndex) throws SQLException {
FilterChainImpl chain = createChain();
String value = chain.resultSet_getString(this, columnIndex);
String value = chain.resultSet_getString(this, getPhysicalColumn(columnIndex));
recycleFilterChain(chain);
return value;
}
@@ -692,7 +698,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public Time getTime(int columnIndex) throws SQLException {
FilterChainImpl chain = createChain();
Time value = chain.resultSet_getTime(this, columnIndex);
Time value = chain.resultSet_getTime(this, getPhysicalColumn(columnIndex));
recycleFilterChain(chain);
return value;
}
@@ -708,7 +714,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public Time getTime(int columnIndex, Calendar cal) throws SQLException {
FilterChainImpl chain = createChain();
Time value = chain.resultSet_getTime(this, columnIndex, cal);
Time value = chain.resultSet_getTime(this, getPhysicalColumn(columnIndex), cal);
recycleFilterChain(chain);
return value;
}
@@ -724,7 +730,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public Timestamp getTimestamp(int columnIndex) throws SQLException {
FilterChainImpl chain = createChain();
Timestamp value = chain.resultSet_getTimestamp(this, columnIndex);
Timestamp value = chain.resultSet_getTimestamp(this, getPhysicalColumn(columnIndex));
recycleFilterChain(chain);
return value;
}
@@ -740,7 +746,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
FilterChainImpl chain = createChain();
Timestamp value = chain.resultSet_getTimestamp(this, columnIndex, cal);
Timestamp value = chain.resultSet_getTimestamp(this, getPhysicalColumn(columnIndex), cal);
recycleFilterChain(chain);
return value;
}
@@ -764,7 +770,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public URL getURL(int columnIndex) throws SQLException {
FilterChainImpl chain = createChain();
URL value = chain.resultSet_getURL(this, columnIndex);
URL value = chain.resultSet_getURL(this, getPhysicalColumn(columnIndex));
recycleFilterChain(chain);
return value;
}
@@ -780,7 +786,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public InputStream getUnicodeStream(int columnIndex) throws SQLException {
FilterChainImpl chain = createChain();
InputStream value = chain.resultSet_getUnicodeStream(this, columnIndex);
InputStream value = chain.resultSet_getUnicodeStream(this, getPhysicalColumn(columnIndex));
recycleFilterChain(chain);
return value;
}
@@ -881,7 +887,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
fetchRowCount = cursorIndex;
}
}
recycleFilterChain(chain);
return moreRows;
}
@@ -955,7 +961,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateArray(int columnIndex, Array x) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateArray(this, columnIndex, x);
chain.resultSet_updateArray(this, getPhysicalColumn(columnIndex), x);
recycleFilterChain(chain);
}
@@ -969,7 +975,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateAsciiStream(int columnIndex, InputStream x) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateAsciiStream(this, columnIndex, x);
chain.resultSet_updateAsciiStream(this, getPhysicalColumn(columnIndex), x);
recycleFilterChain(chain);
}
@@ -983,7 +989,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateAsciiStream(this, columnIndex, x, length);
chain.resultSet_updateAsciiStream(this, getPhysicalColumn(columnIndex), x, length);
recycleFilterChain(chain);
}
@@ -997,7 +1003,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateAsciiStream(int columnIndex, InputStream x, long length) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateAsciiStream(this, columnIndex, x, length);
chain.resultSet_updateAsciiStream(this, getPhysicalColumn(columnIndex), x, length);
recycleFilterChain(chain);
}
@@ -1011,7 +1017,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateBigDecimal(this, columnIndex, x);
chain.resultSet_updateBigDecimal(this, getPhysicalColumn(columnIndex), x);
recycleFilterChain(chain);
}
@@ -1025,7 +1031,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateBinaryStream(int columnIndex, InputStream x) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateBinaryStream(this, columnIndex, x);
chain.resultSet_updateBinaryStream(this, getPhysicalColumn(columnIndex), x);
recycleFilterChain(chain);
}
@@ -1039,7 +1045,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateBinaryStream(this, columnIndex, x, length);
chain.resultSet_updateBinaryStream(this, getPhysicalColumn(columnIndex), x, length);
recycleFilterChain(chain);
}
@@ -1053,7 +1059,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateBinaryStream(int columnIndex, InputStream x, long length) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateBinaryStream(this, columnIndex, x, length);
chain.resultSet_updateBinaryStream(this, getPhysicalColumn(columnIndex), x, length);
recycleFilterChain(chain);
}
@@ -1081,7 +1087,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateBlob(int columnIndex, InputStream x) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateBlob(this, columnIndex, x);
chain.resultSet_updateBlob(this, getPhysicalColumn(columnIndex), x);
recycleFilterChain(chain);
}
@@ -1095,7 +1101,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateBlob(int columnIndex, InputStream x, long length) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateBlob(this, columnIndex, x, length);
chain.resultSet_updateBlob(this, getPhysicalColumn(columnIndex), x, length);
recycleFilterChain(chain);
}
@@ -1109,7 +1115,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateBoolean(int columnIndex, boolean x) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateBoolean(this, columnIndex, x);
chain.resultSet_updateBoolean(this, getPhysicalColumn(columnIndex), x);
recycleFilterChain(chain);
}
@@ -1123,7 +1129,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateByte(int columnIndex, byte x) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateByte(this, columnIndex, x);
chain.resultSet_updateByte(this, getPhysicalColumn(columnIndex), x);
recycleFilterChain(chain);
}
@@ -1137,7 +1143,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateBytes(int columnIndex, byte[] x) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateBytes(this, columnIndex, x);
chain.resultSet_updateBytes(this, getPhysicalColumn(columnIndex), x);
recycleFilterChain(chain);
}
@@ -1151,7 +1157,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateCharacterStream(int columnIndex, Reader x) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateCharacterStream(this, columnIndex, x);
chain.resultSet_updateCharacterStream(this, getPhysicalColumn(columnIndex), x);
recycleFilterChain(chain);
}
@@ -1165,7 +1171,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateCharacterStream(this, columnIndex, x, length);
chain.resultSet_updateCharacterStream(this, getPhysicalColumn(columnIndex), x, length);
recycleFilterChain(chain);
}
@@ -1179,7 +1185,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateCharacterStream(int columnIndex, Reader x, long length) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateCharacterStream(this, columnIndex, x, length);
chain.resultSet_updateCharacterStream(this, getPhysicalColumn(columnIndex), x, length);
recycleFilterChain(chain);
}
@@ -1193,7 +1199,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateClob(int columnIndex, Clob x) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateClob(this, columnIndex, x);
chain.resultSet_updateClob(this, getPhysicalColumn(columnIndex), x);
recycleFilterChain(chain);
}
@@ -1207,7 +1213,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateClob(int columnIndex, Reader x) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateClob(this, columnIndex, x);
chain.resultSet_updateClob(this, getPhysicalColumn(columnIndex), x);
recycleFilterChain(chain);
}
@@ -1221,7 +1227,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateClob(int columnIndex, Reader x, long length) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateClob(this, columnIndex, x, length);
chain.resultSet_updateClob(this, getPhysicalColumn(columnIndex), x, length);
recycleFilterChain(chain);
}
@@ -1235,7 +1241,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateDate(int columnIndex, Date x) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateDate(this, columnIndex, x);
chain.resultSet_updateDate(this, getPhysicalColumn(columnIndex), x);
recycleFilterChain(chain);
}
@@ -1249,7 +1255,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateDouble(int columnIndex, double x) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateDouble(this, columnIndex, x);
chain.resultSet_updateDouble(this, getPhysicalColumn(columnIndex), x);
recycleFilterChain(chain);
}
@@ -1263,7 +1269,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateFloat(int columnIndex, float x) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateFloat(this, columnIndex, x);
chain.resultSet_updateFloat(this, getPhysicalColumn(columnIndex), x);
recycleFilterChain(chain);
}
@@ -1277,7 +1283,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateInt(int columnIndex, int x) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateInt(this, columnIndex, x);
chain.resultSet_updateInt(this, getPhysicalColumn(columnIndex), x);
recycleFilterChain(chain);
}
@@ -1291,7 +1297,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateLong(int columnIndex, long x) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateLong(this, columnIndex, x);
chain.resultSet_updateLong(this, getPhysicalColumn(columnIndex), x);
recycleFilterChain(chain);
}
@@ -1305,7 +1311,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateNCharacterStream(int columnIndex, Reader x) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateNCharacterStream(this, columnIndex, x);
chain.resultSet_updateNCharacterStream(this, getPhysicalColumn(columnIndex), x);
recycleFilterChain(chain);
}
@@ -1319,7 +1325,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateNCharacterStream(int columnIndex, Reader x, long length) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateNCharacterStream(this, columnIndex, x, length);
chain.resultSet_updateNCharacterStream(this, getPhysicalColumn(columnIndex), x, length);
recycleFilterChain(chain);
}
@@ -1333,7 +1339,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateNClob(int columnIndex, NClob x) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateNClob(this, columnIndex, x);
chain.resultSet_updateNClob(this, getPhysicalColumn(columnIndex), x);
recycleFilterChain(chain);
}
@@ -1347,7 +1353,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateNClob(int columnIndex, Reader x) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateNClob(this, columnIndex, x);
chain.resultSet_updateNClob(this, getPhysicalColumn(columnIndex), x);
recycleFilterChain(chain);
}
@@ -1389,7 +1395,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateNull(int columnIndex) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateNull(this, columnIndex);
chain.resultSet_updateNull(this, getPhysicalColumn(columnIndex));
recycleFilterChain(chain);
}
@@ -1403,7 +1409,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateObject(int columnIndex, Object x) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateObject(this, columnIndex, x);
chain.resultSet_updateObject(this, getPhysicalColumn(columnIndex), x);
recycleFilterChain(chain);
}
@@ -1417,7 +1423,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateObject(int columnIndex, Object x, int scaleOrLength) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateObject(this, columnIndex, x, scaleOrLength);
chain.resultSet_updateObject(this, getPhysicalColumn(columnIndex), x, scaleOrLength);
recycleFilterChain(chain);
}
@@ -1431,7 +1437,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateRef(int columnIndex, Ref x) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateRef(this, columnIndex, x);
chain.resultSet_updateRef(this, getPhysicalColumn(columnIndex), x);
recycleFilterChain(chain);
}
@@ -1452,7 +1458,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateRowId(int columnIndex, RowId x) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateRowId(this, columnIndex, x);
chain.resultSet_updateRowId(this, getPhysicalColumn(columnIndex), x);
recycleFilterChain(chain);
}
@@ -1466,7 +1472,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateSQLXML(int columnIndex, SQLXML x) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateSQLXML(this, columnIndex, x);
chain.resultSet_updateSQLXML(this, getPhysicalColumn(columnIndex), x);
recycleFilterChain(chain);
}
@@ -1480,7 +1486,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateShort(int columnIndex, short x) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateShort(this, columnIndex, x);
chain.resultSet_updateShort(this, getPhysicalColumn(columnIndex), x);
recycleFilterChain(chain);
}
@@ -1494,7 +1500,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateString(int columnIndex, String x) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateString(this, columnIndex, x);
chain.resultSet_updateString(this, getPhysicalColumn(columnIndex), x);
recycleFilterChain(chain);
}
@@ -1508,7 +1514,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateTime(int columnIndex, Time x) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateTime(this, columnIndex, x);
chain.resultSet_updateTime(this, getPhysicalColumn(columnIndex), x);
recycleFilterChain(chain);
}
@@ -1522,7 +1528,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
@Override
public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException {
FilterChainImpl chain = createChain();
chain.resultSet_updateTimestamp(this, columnIndex, x);
chain.resultSet_updateTimestamp(this, getPhysicalColumn(columnIndex), x);
recycleFilterChain(chain);
}
@@ -1537,7 +1543,7 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
public boolean wasNull() throws SQLException {
FilterChainImpl chain = createChain();
boolean result = chain.resultSet_wasNull(this);
recycleFilterChain(chain);
return result;
}
@@ -1599,15 +1605,59 @@ public class ResultSetProxyImpl extends WrapperProxyImpl implements ResultSetPro
if (iface == ResultSetProxy.class || iface == ResultSetProxyImpl.class) {
return (T) this;
}
return super.unwrap(iface);
}
public boolean isWrapperFor(Class<?> iface) throws SQLException {
if (iface == ResultSetProxy.class || iface == ResultSetProxyImpl.class) {
return true;
}
return super.isWrapperFor(iface);
}
@Override
public int getPhysicalColumn(int logicColumn) {
if (logicColumnMap == null) {
return logicColumn;
}
return logicColumnMap.get(logicColumn);
}
private int getLogicColumn(int physicalColumn) {
if (physicalColumnMap == null) {
return physicalColumn;
}
return physicalColumnMap.get(physicalColumn);
}
@Override
public int getHiddenColumnCount() {
if (hiddenColumns == null) {
return 0;
}
return hiddenColumns.size();
}
@Override
public List<Integer> getHiddenColumns() {
return this.hiddenColumns;
}
@Override
public void setLogicColumnMap(Map<Integer, Integer> logicColumnMap) {
this.logicColumnMap = logicColumnMap;
}
@Override
public void setPhysicalColumnMap(Map<Integer, Integer> physicalColumnMap) {
this.physicalColumnMap = physicalColumnMap;
}
@Override
public void setHiddenColumns(List<Integer> hiddenColumns) {
this.hiddenColumns = hiddenColumns;
}
}
@@ -56,6 +56,11 @@ public class SQLInsertStatement extends SQLInsertInto implements SQLStatement {
}
}
public void addValue(SQLExpr value) {
value.setParent(this);
values.add(value);
}
public List<SQLExpr> getValues() {
return values;
}
@@ -106,6 +106,7 @@ public class WallConfig implements WallConfigMBean {
private String tenantTablePattern;
private String tenantColumn;
private TenantCallBack tenantCallBack;
private boolean wrapAllow = true;
private boolean metadataAllow = true;
@@ -239,6 +240,14 @@ public class WallConfig implements WallConfigMBean {
this.tenantColumn = tenantColumn;
}
public TenantCallBack getTenantCallBack() {
return tenantCallBack;
}
public void setTenantCallBack(TenantCallBack tenantCallBack) {
this.tenantCallBack = tenantCallBack;
}
public boolean isMetadataAllow() {
return metadataAllow;
}
@@ -695,4 +704,30 @@ public class WallConfig implements WallConfigMBean {
this.callAllow = callAllow;
}
public static abstract interface TenantCallBack {
public static enum StatementType {
SELECT, UPDATE, INSERT, DELETE
}
Object getTenantValue(StatementType statementType, String tableName);
String getTenantColumn(StatementType statementType, String tableName);
/**
* 返回resultset隐藏列名
*
* @param tableName
* @return
*/
String getHiddenColumn(String tableName);
/**
* resultset返回值中如果包含hiddenColumn的回调函数
*
* @param value hiddenColumn对应的值
*/
void resultset_hiddenColumn(Object value);
}
}
@@ -18,10 +18,14 @@ package com.alibaba.druid.wall;
import static com.alibaba.druid.util.Utils.getBoolean;
import java.sql.DatabaseMetaData;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Wrapper;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
@@ -31,11 +35,15 @@ import com.alibaba.druid.proxy.jdbc.CallableStatementProxy;
import com.alibaba.druid.proxy.jdbc.ConnectionProxy;
import com.alibaba.druid.proxy.jdbc.DataSourceProxy;
import com.alibaba.druid.proxy.jdbc.PreparedStatementProxy;
import com.alibaba.druid.proxy.jdbc.ResultSetMetaDataProxyImpl;
import com.alibaba.druid.proxy.jdbc.ResultSetProxy;
import com.alibaba.druid.proxy.jdbc.StatementProxy;
import com.alibaba.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;
import com.alibaba.druid.util.JdbcUtils;
import com.alibaba.druid.util.ServletPathMatcher;
import com.alibaba.druid.util.StringUtils;
import com.alibaba.druid.wall.WallConfig.TenantCallBack;
import com.alibaba.druid.wall.spi.DB2WallProvider;
import com.alibaba.druid.wall.spi.MySqlWallProvider;
import com.alibaba.druid.wall.spi.OracleWallProvider;
@@ -469,7 +477,9 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean {
createWallContext(statement);
try {
sql = check(sql);
return chain.statement_executeQuery(statement, sql);
ResultSetProxy resultSetProxy = chain.statement_executeQuery(statement, sql);
preprocessResultSet(resultSetProxy);
return resultSetProxy;
} catch (SQLException ex) {
incrementExecuteErrorCount();
throw ex;
@@ -579,7 +589,9 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean {
public ResultSetProxy preparedStatement_executeQuery(FilterChain chain, PreparedStatementProxy statement)
throws SQLException {
try {
return chain.preparedStatement_executeQuery(statement);
ResultSetProxy resultSetProxy = chain.preparedStatement_executeQuery(statement);
preprocessResultSet(resultSetProxy);
return resultSetProxy;
} catch (SQLException ex) {
incrementExecuteErrorCount(statement);
throw ex;
@@ -601,6 +613,20 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean {
}
}
@Override
public ResultSetProxy statement_getResultSet(FilterChain chain, StatementProxy statement) throws SQLException {
ResultSetProxy resultSetProxy = chain.statement_getResultSet(statement);
preprocessResultSet(resultSetProxy);
return resultSetProxy;
}
@Override
public ResultSetProxy statement_getGeneratedKeys(FilterChain chain, StatementProxy statement) throws SQLException {
ResultSetProxy resultSetProxy = chain.statement_getGeneratedKeys(statement);
preprocessResultSet(resultSetProxy);
return resultSetProxy;
}
public void setSqlStatAttribute(StatementProxy stmt) {
WallContext context = WallContext.current();
if (context == null) {
@@ -630,7 +656,7 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean {
provider.addUpdateCount(sqlStat, updateCount);
}
}
public void incrementExecuteErrorCount(PreparedStatementProxy statement) {
WallSqlStat sqlStat = (WallSqlStat) statement.getAttribute(ATTR_SQL_STAT);
if (sqlStat != null) {
@@ -736,6 +762,34 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean {
provider.addFetchRowCount(sqlStat, fetchRowCount);
}
// ////////////////
@Override
public boolean resultSet_next(FilterChain chain, ResultSetProxy resultSet) throws SQLException {
boolean hasNext = chain.resultSet_next(resultSet);
TenantCallBack callback = provider.getConfig().getTenantCallBack();
if (callback != null && hasNext) {
List<Integer> hiddenColumns = resultSet.getHiddenColumns();
if (hiddenColumns != null && hiddenColumns.size() > 0) {
for (Integer columnIndex : hiddenColumns) {
Object value = resultSet.getResultSetRaw().getObject(columnIndex);
callback.resultset_hiddenColumn(value);
}
}
}
return hasNext;
}
@Override
public ResultSetMetaData resultSet_getMetaData(FilterChain chain, ResultSetProxy resultSet) throws SQLException {
ResultSetMetaData metaData = chain.resultSet_getMetaData(resultSet);
if (metaData == null) {
return null;
}
return new ResultSetMetaDataProxyImpl(metaData, chain.getDataSource().createMetaDataId(), resultSet);
}
public long getViolationCount() {
return this.provider.getViolationCount();
}
@@ -751,4 +805,57 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean {
public boolean checkValid(String sql) {
return provider.checkValid(sql);
}
private void preprocessResultSet(ResultSetProxy resultSet) throws SQLException {
if (resultSet == null) {
return;
}
ResultSetMetaData metaData = resultSet.getResultSetRaw().getMetaData();
if (metaData == null) {
return;
}
TenantCallBack tenantCallBack = provider.getConfig().getTenantCallBack();
String tenantTablePattern = provider.getConfig().getTenantTablePattern();
if (tenantCallBack == null && (tenantTablePattern == null || tenantTablePattern.length() == 0)) {
return;
}
Map<Integer, Integer> logicColumnMap = new HashMap<Integer, Integer>();
Map<Integer, Integer> physicalColumnMap = new HashMap<Integer, Integer>();
List<Integer> hiddenColumns = new ArrayList<Integer>();
for (int physicalColumn = 1, logicColumn = 1; physicalColumn <= metaData.getColumnCount(); physicalColumn++) {
boolean isHidden = false;
String tableName = metaData.getTableName(physicalColumn);
String hiddenColumn = null;
if (tenantCallBack != null) {
hiddenColumn = tenantCallBack.getHiddenColumn(tableName);
}
if (StringUtils.isEmpty(hiddenColumn)
&& (tableName == null || ServletPathMatcher.getInstance().matches(tenantTablePattern, tableName))) {
hiddenColumn = provider.getConfig().getTenantColumn();
}
if (!StringUtils.isEmpty(hiddenColumn)) {
String columnName = metaData.getColumnName(physicalColumn);
if (hiddenColumn.equalsIgnoreCase(columnName)) {
hiddenColumns.add(physicalColumn);
isHidden = true;
}
}
if (!isHidden) {
logicColumnMap.put(logicColumn, physicalColumn);
physicalColumnMap.put(physicalColumn, logicColumn);
logicColumn++;
}
}
if (hiddenColumns.size() > 0) {
resultSet.setLogicColumnMap(logicColumnMap);
resultSet.setPhysicalColumnMap(physicalColumnMap);
resultSet.setHiddenColumns(hiddenColumns);
}
}
}
@@ -27,6 +27,7 @@ import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Set;
import java.util.Stack;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
@@ -71,6 +72,7 @@ import com.alibaba.druid.sql.ast.statement.SQLDropViewStatement;
import com.alibaba.druid.sql.ast.statement.SQLExprTableSource;
import com.alibaba.druid.sql.ast.statement.SQLInsertInto;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause;
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource;
import com.alibaba.druid.sql.ast.statement.SQLRollbackStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelect;
@@ -85,6 +87,7 @@ import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement;
import com.alibaba.druid.sql.ast.statement.SQLUnionOperator;
import com.alibaba.druid.sql.ast.statement.SQLUnionQuery;
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.ast.statement.SQLUseStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlBooleanExpr;
@@ -92,6 +95,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlOutFileExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCommitStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDescribeStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlReplaceStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetCharSetStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSetNamesStatement;
@@ -102,6 +106,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreateSequenceStateme
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMergeStatement;
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleMultiInsertStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerExecStatement;
import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement;
import com.alibaba.druid.sql.visitor.ExportParameterVisitor;
import com.alibaba.druid.sql.visitor.SQLEvalVisitor;
import com.alibaba.druid.sql.visitor.SQLEvalVisitorUtils;
@@ -110,7 +115,10 @@ import com.alibaba.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;
import com.alibaba.druid.util.JdbcUtils;
import com.alibaba.druid.util.ServletPathMatcher;
import com.alibaba.druid.util.StringUtils;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallConfig.TenantCallBack;
import com.alibaba.druid.wall.WallConfig.TenantCallBack.StatementType;
import com.alibaba.druid.wall.WallContext;
import com.alibaba.druid.wall.WallProvider;
import com.alibaba.druid.wall.WallSqlTableStat;
@@ -235,6 +243,8 @@ public class WallVisitorUtils {
if (!visitor.getConfig().isInsertAllow()) {
addViolation(visitor, ErrorCode.INSERT_NOT_ALLOW, "insert not allow", x);
}
checkInsertForMultiTenant(visitor, x);
}
public static void checkSelelct(WallVisitor visitor, SQLSelectQueryBlock x) {
@@ -273,7 +283,8 @@ public class WallVisitorUtils {
}
}
}
checkConditionForMultiTenant(visitor, x.getWhere(), x);
checkSelectForMultiTenant(visitor, x);
// checkConditionForMultiTenant(visitor, x.getWhere(), x);
}
public static void checkHaving(WallVisitor visitor, SQLExpr x) {
@@ -327,7 +338,7 @@ public class WallVisitorUtils {
}
}
checkConditionForMultiTenant(visitor, x.getWhere(), x);
// checkConditionForMultiTenant(visitor, x.getWhere(), x);
}
private static boolean isSimpleConstExpr(SQLExpr sqlExpr) {
@@ -377,6 +388,316 @@ public class WallVisitorUtils {
}
private static void checkJoinSelectForMultiTenant(WallVisitor visitor, SQLJoinTableSource join,
SQLSelectQueryBlock x) {
TenantCallBack tenantCallBack = visitor.getConfig().getTenantCallBack();
String tenantTablePattern = visitor.getConfig().getTenantTablePattern();
if (tenantCallBack == null && (tenantTablePattern == null || tenantTablePattern.length() == 0)) {
return;
}
SQLTableSource right = join.getRight();
if (right instanceof SQLExprTableSource) {
SQLExpr tableExpr = ((SQLExprTableSource) right).getExpr();
if (tableExpr instanceof SQLIdentifierExpr) {
String tableName = ((SQLIdentifierExpr) tableExpr).getName();
String alias = null;
String tenantColumn = null;
if (tenantCallBack != null) {
tenantColumn = tenantCallBack.getTenantColumn(StatementType.SELECT, tableName);
}
if (StringUtils.isEmpty(tenantColumn)
&& ServletPathMatcher.getInstance().matches(tenantTablePattern, tableName)) {
tenantColumn = visitor.getConfig().getTenantColumn();
}
if (!StringUtils.isEmpty(tenantColumn)) {
alias = right.getAlias();
if (alias == null) {
alias = tableName;
}
SQLExpr item = null;
if (alias != null) {
item = new SQLPropertyExpr(new SQLIdentifierExpr(alias), tenantColumn);
} else {
item = new SQLIdentifierExpr(tenantColumn);
}
SQLSelectItem selectItem = new SQLSelectItem(item);
x.getSelectList().add(selectItem);
visitor.setSqlModified(true);
}
}
}
}
private static boolean isSelectStatmentForMultiTenant(SQLSelectQueryBlock queryBlock) {
SQLObject parent = queryBlock.getParent();
while (parent != null) {
if (parent instanceof SQLUnionQuery) {
SQLObject x = parent;
parent = x.getParent();
} else {
break;
}
}
if (!(parent instanceof SQLSelect)) {
return false;
}
parent = ((SQLSelect) parent).getParent();
if (parent instanceof SQLSelectStatement) {
return true;
}
return false;
}
private static void checkSelectForMultiTenant(WallVisitor visitor, SQLSelectQueryBlock x) {
TenantCallBack tenantCallBack = visitor.getConfig().getTenantCallBack();
String tenantTablePattern = visitor.getConfig().getTenantTablePattern();
if (tenantCallBack == null && (tenantTablePattern == null || tenantTablePattern.length() == 0)) {
return;
}
if (x == null) {
throw new IllegalStateException("x is null");
}
if (!isSelectStatmentForMultiTenant(x)) {
return;
}
SQLTableSource tableSource = x.getFrom();
String alias = null;
String matchTableName = null;
String tenantColumn = null;
if (tableSource instanceof SQLExprTableSource) {
SQLExpr tableExpr = ((SQLExprTableSource) tableSource).getExpr();
if (tableExpr instanceof SQLIdentifierExpr) {
String tableName = ((SQLIdentifierExpr) tableExpr).getName();
if (tenantCallBack != null) {
tenantColumn = tenantCallBack.getTenantColumn(StatementType.SELECT, tableName);
}
if (StringUtils.isEmpty(tenantColumn)
&& ServletPathMatcher.getInstance().matches(tenantTablePattern, tableName)) {
tenantColumn = visitor.getConfig().getTenantColumn();
}
if (!StringUtils.isEmpty(tenantColumn)) {
matchTableName = tableName;
alias = tableSource.getAlias();
}
}
} else if (tableSource instanceof SQLJoinTableSource) {
SQLJoinTableSource join = (SQLJoinTableSource) tableSource;
if (join.getLeft() instanceof SQLExprTableSource) {
SQLExpr tableExpr = ((SQLExprTableSource) join.getLeft()).getExpr();
if (tableExpr instanceof SQLIdentifierExpr) {
String tableName = ((SQLIdentifierExpr) tableExpr).getName();
if (tenantCallBack != null) {
tenantColumn = tenantCallBack.getTenantColumn(StatementType.SELECT, tableName);
}
if (StringUtils.isEmpty(tenantColumn)
&& ServletPathMatcher.getInstance().matches(tenantTablePattern, tableName)) {
tenantColumn = visitor.getConfig().getTenantColumn();
}
if (!StringUtils.isEmpty(tenantColumn)) {
matchTableName = tableName;
alias = join.getLeft().getAlias();
if (alias == null) {
alias = tableName;
}
}
}
checkJoinSelectForMultiTenant(visitor, join, x);
} else {
checkJoinSelectForMultiTenant(visitor, join, x);
}
}
if (matchTableName == null) {
return;
}
SQLExpr item = null;
if (alias != null) {
item = new SQLPropertyExpr(new SQLIdentifierExpr(alias), tenantColumn);
} else {
item = new SQLIdentifierExpr(tenantColumn);
}
SQLSelectItem selectItem = new SQLSelectItem(item);
x.getSelectList().add(selectItem);
visitor.setSqlModified(true);
}
private static void checkUpdateForMultiTenant(WallVisitor visitor, SQLUpdateStatement x) {
TenantCallBack tenantCallBack = visitor.getConfig().getTenantCallBack();
String tenantTablePattern = visitor.getConfig().getTenantTablePattern();
if (tenantCallBack == null && (tenantTablePattern == null || tenantTablePattern.length() == 0)) {
return;
}
if (x == null) {
throw new IllegalStateException("x is null");
}
SQLTableSource tableSource = x.getTableSource();
String alias = null;
String matchTableName = null;
String tenantColumn = null;
if (tableSource instanceof SQLExprTableSource) {
SQLExpr tableExpr = ((SQLExprTableSource) tableSource).getExpr();
if (tableExpr instanceof SQLIdentifierExpr) {
String tableName = ((SQLIdentifierExpr) tableExpr).getName();
if (tenantCallBack != null) {
tenantColumn = tenantCallBack.getTenantColumn(StatementType.UPDATE, tableName);
}
if (StringUtils.isEmpty(tenantColumn)
&& ServletPathMatcher.getInstance().matches(tenantTablePattern, tableName)) {
tenantColumn = visitor.getConfig().getTenantColumn();
}
if (!StringUtils.isEmpty(tenantColumn)) {
matchTableName = tableName;
alias = tableSource.getAlias();
}
}
}
if (matchTableName == null) {
return;
}
SQLExpr item = null;
if (alias != null) {
item = new SQLPropertyExpr(new SQLIdentifierExpr(alias), tenantColumn);
} else {
item = new SQLIdentifierExpr(tenantColumn);
}
SQLExpr value = generateTenantValue(visitor, alias, StatementType.UPDATE, matchTableName);
SQLUpdateSetItem updateSetItem = new SQLUpdateSetItem();
updateSetItem.setColumn(item);
updateSetItem.setValue(value);
x.getItems().add(updateSetItem);
visitor.setSqlModified(true);
}
private static void checkInsertForMultiTenant(WallVisitor visitor, SQLInsertInto x) {
TenantCallBack tenantCallBack = visitor.getConfig().getTenantCallBack();
String tenantTablePattern = visitor.getConfig().getTenantTablePattern();
if (tenantCallBack == null && (tenantTablePattern == null || tenantTablePattern.length() == 0)) {
return;
}
if (x == null) {
throw new IllegalStateException("x is null");
}
SQLExprTableSource tableSource = x.getTableSource();
String alias = null;
String matchTableName = null;
String tenantColumn = null;
SQLExpr tableExpr = tableSource.getExpr();
if (tableExpr instanceof SQLIdentifierExpr) {
String tableName = ((SQLIdentifierExpr) tableExpr).getName();
if (tenantCallBack != null) {
tenantColumn = tenantCallBack.getTenantColumn(StatementType.INSERT, tableName);
}
if (StringUtils.isEmpty(tenantColumn)
&& ServletPathMatcher.getInstance().matches(tenantTablePattern, tableName)) {
tenantColumn = visitor.getConfig().getTenantColumn();
}
if (!StringUtils.isEmpty(tenantColumn)) {
matchTableName = tableName;
alias = tableSource.getAlias();
}
}
if (matchTableName == null) {
return;
}
SQLExpr item = null;
if (alias != null) {
item = new SQLPropertyExpr(new SQLIdentifierExpr(alias), tenantColumn);
} else {
item = new SQLIdentifierExpr(tenantColumn);
}
SQLExpr value = generateTenantValue(visitor, alias, StatementType.INSERT, matchTableName);
// add insert item and value
x.getColumns().add(item);
List<ValuesClause> valuesClauses = null;
ValuesClause valuesClause = null;
if (x instanceof MySqlInsertStatement) {
valuesClauses = ((MySqlInsertStatement) x).getValuesList();
} else if (x instanceof SQLServerInsertStatement) {
valuesClauses = ((MySqlInsertStatement) x).getValuesList();
} else {
valuesClause = x.getValues();
}
if (valuesClauses != null && valuesClauses.size() > 0) {
for (ValuesClause clause : valuesClauses) {
clause.addValue(value);
}
}
if (valuesClause != null) {
valuesClause.addValue(value);
}
// insert .. select
SQLSelect select = x.getQuery();
if (select != null) {
List<SQLSelectQueryBlock> queryBlocks = splitSQLSelectQuery(select.getQuery());
for (SQLSelectQueryBlock queryBlock : queryBlocks) {
queryBlock.getSelectList().add(new SQLSelectItem(value));
}
}
visitor.setSqlModified(true);
}
private static List<SQLSelectQueryBlock> splitSQLSelectQuery(SQLSelectQuery x) {
List<SQLSelectQueryBlock> groupList = new ArrayList<SQLSelectQueryBlock>();
Stack<SQLSelectQuery> stack = new Stack<SQLSelectQuery>();
stack.push(x);
do {
SQLSelectQuery query = stack.pop();
if (query instanceof SQLSelectQueryBlock) {
groupList.add((SQLSelectQueryBlock) query);
} else if (query instanceof SQLUnionQuery) {
SQLUnionQuery unionQuery = (SQLUnionQuery) query;
stack.push(unionQuery.getLeft());
stack.push(unionQuery.getRight());
}
} while (!stack.empty());
return groupList;
}
@Deprecated
public static void checkConditionForMultiTenant(WallVisitor visitor, SQLExpr x, SQLObject parent) {
String tenantTablePattern = visitor.getConfig().getTenantTablePattern();
if (tenantTablePattern == null || tenantTablePattern.length() == 0) {
@@ -389,12 +710,16 @@ public class WallVisitorUtils {
String alias = null;
SQLTableSource tableSource;
StatementType statementType = null;
if (parent instanceof SQLDeleteStatement) {
tableSource = ((SQLDeleteStatement) parent).getTableSource();
statementType = StatementType.DELETE;
} else if (parent instanceof SQLUpdateStatement) {
tableSource = ((SQLUpdateStatement) parent).getTableSource();
statementType = StatementType.UPDATE;
} else if (parent instanceof SQLSelectQueryBlock) {
tableSource = ((SQLSelectQueryBlock) parent).getFrom();
statementType = StatementType.SELECT;
} else {
throw new IllegalStateException("not support parent : " + parent.getClass());
}
@@ -423,9 +748,9 @@ public class WallVisitorUtils {
}
}
checkJoinConditionForMultiTenant(visitor, join, false);
checkJoinConditionForMultiTenant(visitor, join, false, statementType);
} else {
checkJoinConditionForMultiTenant(visitor, join, true);
checkJoinConditionForMultiTenant(visitor, join, true, statementType);
}
}
@@ -433,7 +758,7 @@ public class WallVisitorUtils {
return;
}
SQLBinaryOpExpr tenantCondition = cretateTenantCondition(visitor, alias);
SQLBinaryOpExpr tenantCondition = createTenantCondition(visitor, alias, statementType, matchTableName);
SQLExpr condition;
if (x == null) {
@@ -457,7 +782,9 @@ public class WallVisitorUtils {
}
}
public static void checkJoinConditionForMultiTenant(WallVisitor visitor, SQLJoinTableSource join, boolean checkLeft) {
@Deprecated
public static void checkJoinConditionForMultiTenant(WallVisitor visitor, SQLJoinTableSource join,
boolean checkLeft, StatementType statementType) {
String tenantTablePattern = visitor.getConfig().getTenantTablePattern();
if (tenantTablePattern == null || tenantTablePattern.length() == 0) {
return;
@@ -476,7 +803,7 @@ public class WallVisitorUtils {
if (alias == null) {
alias = tableName;
}
SQLBinaryOpExpr tenantCondition = cretateTenantCondition(visitor, alias);
SQLBinaryOpExpr tenantCondition = createTenantCondition(visitor, alias, statementType, tableName);
if (condition == null) {
condition = tenantCondition;
@@ -493,25 +820,39 @@ public class WallVisitorUtils {
}
}
private static SQLBinaryOpExpr cretateTenantCondition(WallVisitor visitor, String alias) {
@Deprecated
private static SQLBinaryOpExpr createTenantCondition(WallVisitor visitor, String alias,
StatementType statementType, String tableName) {
SQLExpr left, right;
if (alias != null) {
left = new SQLPropertyExpr(new SQLIdentifierExpr(alias), visitor.getConfig().getTenantColumn());
} else {
left = new SQLIdentifierExpr(visitor.getConfig().getTenantColumn());
}
right = generateTenantValue(visitor, alias, statementType, tableName);
SQLBinaryOpExpr tenantCondition = new SQLBinaryOpExpr(left, SQLBinaryOperator.Equality, right);
return tenantCondition;
}
private static SQLExpr generateTenantValue(WallVisitor visitor, String alias, StatementType statementType,
String tableName) {
SQLExpr value;
TenantCallBack callBack = visitor.getConfig().getTenantCallBack();
if (callBack != null) {
WallProvider.setTenantValue(callBack.getTenantValue(statementType, tableName));
}
Object tenantValue = WallProvider.getTenantValue();
if (tenantValue instanceof Number) {
right = new SQLNumberExpr((Number) tenantValue);
value = new SQLNumberExpr((Number) tenantValue);
} else if (tenantValue instanceof String) {
right = new SQLCharExpr((String) tenantValue);
value = new SQLCharExpr((String) tenantValue);
} else {
throw new IllegalStateException("tenant value not support type " + tenantValue);
}
SQLBinaryOpExpr tenantCondition = new SQLBinaryOpExpr(left, SQLBinaryOperator.Equality, right);
return tenantCondition;
return value;
}
public static void checkReadOnly(WallVisitor visitor, SQLTableSource tableSource) {
@@ -573,7 +914,7 @@ public class WallVisitorUtils {
}
}
checkConditionForMultiTenant(visitor, where, x);
checkUpdateForMultiTenant(visitor, x);
}
public static Object getValue(WallVisitor visitor, SQLBinaryOpExpr x) {