mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
@@ -19,7 +19,7 @@ public final class VERSION {
|
||||
|
||||
public final static int MajorVersion = 0;
|
||||
public final static int MinorVersion = 2;
|
||||
public final static int RevisionVersion = 17;
|
||||
public final static int RevisionVersion = 18;
|
||||
|
||||
public static String getVersionNumber() {
|
||||
return VERSION.MajorVersion + "." + VERSION.MinorVersion + "." + VERSION.RevisionVersion;
|
||||
|
||||
@@ -248,8 +248,6 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
|
||||
this.useLocalSessionState = useLocalSessionState;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean isOracle() {
|
||||
return isOracle;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import javax.management.JMException;
|
||||
import javax.management.ObjectName;
|
||||
@@ -45,6 +46,8 @@ import javax.sql.ConnectionEventListener;
|
||||
import javax.sql.ConnectionPoolDataSource;
|
||||
import javax.sql.PooledConnection;
|
||||
|
||||
import org.h2.util.StringUtils;
|
||||
|
||||
import com.alibaba.druid.TransactionTimeoutException;
|
||||
import com.alibaba.druid.VERSION;
|
||||
import com.alibaba.druid.filter.AutoLoad;
|
||||
@@ -91,6 +94,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
// stats
|
||||
private final AtomicLong recycleErrorCount = new AtomicLong();
|
||||
private long connectCount = 0L;
|
||||
private long closeCount = 0L;
|
||||
private final AtomicLong connectErrorCount = new AtomicLong();
|
||||
@@ -265,6 +269,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
preparedStatementCount.set(0);
|
||||
transactionHistogram.reset();
|
||||
cachedPreparedStatementDeleteCount.set(0);
|
||||
recycleErrorCount.set(0);
|
||||
}
|
||||
|
||||
public boolean isEnable() {
|
||||
@@ -379,6 +384,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
return;
|
||||
}
|
||||
|
||||
final ReentrantLock lock = this.lock;
|
||||
try {
|
||||
lock.lockInterruptibly();
|
||||
} catch (InterruptedException e) {
|
||||
@@ -469,18 +475,15 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
initExceptionSorter();
|
||||
initValidConnectionChecker();
|
||||
|
||||
if (driver.getClass().getName().equals("com.mysql.jdbc.Driver")) {
|
||||
if (this.isPoolPreparedStatements()) {
|
||||
LOG.error("mysql should not use 'PoolPreparedStatements'");
|
||||
}
|
||||
}
|
||||
|
||||
if (useGloalDataSourceStat) {
|
||||
if (isUseGloalDataSourceStat()) {
|
||||
dataSourceStat = JdbcDataSourceStat.getGlobal();
|
||||
if (dataSourceStat == null) {
|
||||
dataSourceStat = new JdbcDataSourceStat("Global", "Global", this.dbType);
|
||||
JdbcDataSourceStat.setGlobal(dataSourceStat);
|
||||
}
|
||||
if (dataSourceStat.getDbType() == null) {
|
||||
dataSourceStat.setDbType(this.getDbType());
|
||||
}
|
||||
} else {
|
||||
dataSourceStat = new JdbcDataSourceStat(this.name, this.jdbcUrl, this.dbType);
|
||||
}
|
||||
@@ -1042,8 +1045,13 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
}
|
||||
|
||||
LOG.error("recyle error", e);
|
||||
recycleErrorCount.incrementAndGet();
|
||||
}
|
||||
}
|
||||
|
||||
public long getRecycleErrorCount() {
|
||||
return recycleErrorCount.get();
|
||||
}
|
||||
|
||||
public void clearStatementCache() throws SQLException {
|
||||
lock.lock();
|
||||
@@ -1228,7 +1236,15 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
|
||||
@Override
|
||||
public Connection getConnection(String username, String password) throws SQLException {
|
||||
throw new UnsupportedOperationException("Not supported by DruidDataSource");
|
||||
if (!StringUtils.equals(username, this.username)) {
|
||||
throw new UnsupportedOperationException("Not supported by DruidDataSource");
|
||||
}
|
||||
|
||||
if (!StringUtils.equals(password, this.password)) {
|
||||
throw new UnsupportedOperationException("Not supported by DruidDataSource");
|
||||
}
|
||||
|
||||
return getConnection();
|
||||
}
|
||||
|
||||
public long getCreateCount() {
|
||||
|
||||
+17
@@ -61,6 +61,23 @@ public class MySqlParameterizedOutputVisitor extends MySqlOutputVisitor {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int numberCount = 0;
|
||||
for (int i = name.length() - 1; i >= 0; --i) {
|
||||
char ch = name.charAt(i);
|
||||
if (ch < '0' || ch > '9') {
|
||||
break;
|
||||
} else {
|
||||
numberCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (numberCount > 1) {
|
||||
int numPos = name.length() - numberCount;
|
||||
String realName = name.substring(0, numPos);
|
||||
print(realName);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
print(name);
|
||||
return false;
|
||||
|
||||
@@ -70,9 +70,18 @@ public class JdbcDataSourceStat implements JdbcDataSourceStatMBean {
|
||||
|
||||
private final AtomicLong blobOpenCount = new AtomicLong();
|
||||
|
||||
private static JdbcDataSourceStat global = new JdbcDataSourceStat(
|
||||
"global",
|
||||
"global");
|
||||
private static JdbcDataSourceStat global;
|
||||
|
||||
static {
|
||||
String dbType = null;
|
||||
{
|
||||
String property = System.getProperty("druid.globalDbType");
|
||||
if (property != null && property.length() > 0) {
|
||||
dbType = property;
|
||||
}
|
||||
}
|
||||
global = new JdbcDataSourceStat("Global", "Global", dbType);
|
||||
}
|
||||
|
||||
public static JdbcDataSourceStat getGlobal() {
|
||||
return global;
|
||||
@@ -114,6 +123,14 @@ public class JdbcDataSourceStat implements JdbcDataSourceStatMBean {
|
||||
sqlStatMap = new LRUCache<String, JdbcSqlStat>(maxSize, 16, 0.75f, false);
|
||||
}
|
||||
|
||||
public String getDbType() {
|
||||
return dbType;
|
||||
}
|
||||
|
||||
public void setDbType(String dbType) {
|
||||
this.dbType = dbType;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
blobOpenCount.set(0);
|
||||
clobOpenCount.set(0);
|
||||
@@ -266,6 +283,7 @@ public class JdbcDataSourceStat implements JdbcDataSourceStatMBean {
|
||||
if (sqlStat == null) {
|
||||
sqlStat = new JdbcSqlStat(sql);
|
||||
sqlStat.setDbType(this.dbType);
|
||||
sqlStat.setName(this.name);
|
||||
sqlStatMap.put(sql, sqlStat);
|
||||
}
|
||||
|
||||
|
||||
@@ -191,9 +191,11 @@ public class WebStatFilter implements Filter {
|
||||
|
||||
if (isProfileEnable()) {
|
||||
Profiler.release(nanos);
|
||||
|
||||
|
||||
Map<ProfileEntryKey, ProfileEntryReqStat> requestStatsMap = Profiler.getStatsMap();
|
||||
uriStat.getProfiletat().record(requestStatsMap);
|
||||
if (uriStat != null) {
|
||||
uriStat.getProfiletat().record(requestStatsMap);
|
||||
}
|
||||
Profiler.removeLocal();
|
||||
}
|
||||
}
|
||||
@@ -380,8 +382,9 @@ public class WebStatFilter implements Filter {
|
||||
StatFilterContext.getInstance().addContextListener(statFilterContextListener);
|
||||
|
||||
this.contextPath = DruidWebUtils.getContextPath(config.getServletContext());
|
||||
webAppStat = new WebAppStat(contextPath, this.sessionStatMaxCount);
|
||||
|
||||
if (webAppStat == null) {
|
||||
webAppStat = new WebAppStat(contextPath, this.sessionStatMaxCount);
|
||||
}
|
||||
WebAppStatManager.getInstance().addWebAppStatSet(webAppStat);
|
||||
}
|
||||
|
||||
@@ -410,6 +413,10 @@ public class WebStatFilter implements Filter {
|
||||
this.profileEnable = profileEnable;
|
||||
}
|
||||
|
||||
public void setWebAppStat(WebAppStat webAppStat) {
|
||||
this.webAppStat = webAppStat;
|
||||
}
|
||||
|
||||
public WebAppStat getWebAppStat() {
|
||||
return webAppStat;
|
||||
}
|
||||
|
||||
@@ -63,7 +63,6 @@ import com.alibaba.druid.wall.WallContext;
|
||||
import com.alibaba.druid.wall.WallProvider;
|
||||
import com.alibaba.druid.wall.WallSqlTableStat;
|
||||
import com.alibaba.druid.wall.WallVisitor;
|
||||
import com.alibaba.druid.wall.spi.WallVisitorUtils.WallConditionContext;
|
||||
import com.alibaba.druid.wall.violation.ErrorCode;
|
||||
import com.alibaba.druid.wall.violation.IllegalSQLObjectViolation;
|
||||
|
||||
@@ -178,13 +177,13 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi
|
||||
public boolean visit(Limit x) {
|
||||
if (x.getRowCount() instanceof SQLNumericLiteralExpr) {
|
||||
WallContext context = WallContext.current();
|
||||
|
||||
|
||||
int rowCount = ((SQLNumericLiteralExpr) x.getRowCount()).getNumber().intValue();
|
||||
if (rowCount == 0) {
|
||||
if (context != null) {
|
||||
context.incrementWarnnings();
|
||||
}
|
||||
|
||||
|
||||
if (!provider.getConfig().isLimitZeroAllow()) {
|
||||
this.getViolations().add(new IllegalSQLObjectViolation(ErrorCode.LIMIT_ZERO, "limit row 0",
|
||||
this.toSQL(x)));
|
||||
@@ -209,8 +208,21 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi
|
||||
if (!checkVar(x.getParent(), x.getName())) {
|
||||
boolean isTop = WallVisitorUtils.isTopNoneFromSelect(this, x);
|
||||
if (!isTop) {
|
||||
violations.add(new IllegalSQLObjectViolation(ErrorCode.VARIANT_DENY, "variable not allow : "
|
||||
+ x.getName(), toSQL(x)));
|
||||
boolean allow = true;
|
||||
if (isDeny(varName)) {
|
||||
allow = false;
|
||||
}
|
||||
|
||||
if (allow) {
|
||||
if (WallVisitorUtils.isWhereOrHaving(x)) {
|
||||
allow = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!allow) {
|
||||
violations.add(new IllegalSQLObjectViolation(ErrorCode.VARIANT_DENY, "variable not allow : "
|
||||
+ x.getName(), toSQL(x)));
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -248,6 +260,14 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isDeny(String varName) {
|
||||
if (varName.startsWith("@@")) {
|
||||
varName = varName.substring(2);
|
||||
}
|
||||
|
||||
return config.getDenyVariants().contains(varName);
|
||||
}
|
||||
|
||||
public boolean visit(SQLVariantRefExpr x) {
|
||||
String varName = x.getName();
|
||||
@@ -256,10 +276,23 @@ public class MySqlWallVisitor extends MySqlASTVisitorAdapter implements WallVisi
|
||||
}
|
||||
|
||||
if (varName.startsWith("@@") && !checkVar(x.getParent(), x.getName())) {
|
||||
boolean noneCondition = WallVisitorUtils.getWallConditionContext() == null;
|
||||
if (!noneCondition) {
|
||||
violations.add(new IllegalSQLObjectViolation(ErrorCode.VARIANT_DENY, "variable not allow : "
|
||||
+ x.getName(), toSQL(x)));
|
||||
boolean isTop = WallVisitorUtils.isTopNoneFromSelect(this, x);
|
||||
if (!isTop) {
|
||||
boolean allow = true;
|
||||
if (isDeny(varName)) {
|
||||
allow = false;
|
||||
}
|
||||
|
||||
if (allow) {
|
||||
if (WallVisitorUtils.isWhereOrHaving(x)) {
|
||||
allow = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!allow) {
|
||||
violations.add(new IllegalSQLObjectViolation(ErrorCode.VARIANT_DENY, "variable not allow : "
|
||||
+ x.getName(), toSQL(x)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLRollbackStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelect;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectGroupByClause;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectItem;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
|
||||
@@ -622,6 +623,40 @@ public class WallVisitorUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isWhereOrHaving(SQLObject x) {
|
||||
if (x == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
SQLObject parent = x.getParent();
|
||||
|
||||
if (parent == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parent instanceof SQLSelectQueryBlock) {
|
||||
SQLSelectQueryBlock query = (SQLSelectQueryBlock) parent;
|
||||
if (query.getWhere() == x) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (parent instanceof SQLSelectGroupByClause) {
|
||||
SQLSelectGroupByClause groupBy = (SQLSelectGroupByClause) parent;
|
||||
if (x == groupBy.getHaving()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
x = parent;
|
||||
}
|
||||
}
|
||||
|
||||
public static class WallConditionContext {
|
||||
|
||||
private boolean partAlwayrue;
|
||||
|
||||
Reference in New Issue
Block a user