From 20696449f9fa1cd43b5a7aadd44ab7bdcd00cbbd Mon Sep 17 00:00:00 2001 From: wenshao Date: Thu, 29 Nov 2012 16:20:06 +0800 Subject: [PATCH] add validationQuery check --- .../alibaba/druid/pool/DruidDataSource.java | 72 ++++++++++++++++++- .../bvt/pool/ValidationQueryLogDB2Test.java | 44 ++++++++++++ .../bvt/pool/ValidationQueryLogTest.java | 44 ++++++++++++ 3 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/pool/ValidationQueryLogDB2Test.java create mode 100644 src/test/java/com/alibaba/druid/bvt/pool/ValidationQueryLogTest.java diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java index 9de9fa994a..ebdf806952 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java @@ -63,6 +63,12 @@ import com.alibaba.druid.pool.vendor.SybaseExceptionSorter; import com.alibaba.druid.proxy.DruidDriver; import com.alibaba.druid.proxy.jdbc.DataSourceProxyConfig; import com.alibaba.druid.proxy.jdbc.TransactionInfo; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.ast.statement.SQLSelectQuery; +import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; +import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; +import com.alibaba.druid.sql.parser.SQLParserUtils; +import com.alibaba.druid.sql.parser.SQLStatementParser; import com.alibaba.druid.stat.DruidDataSourceStatManager; import com.alibaba.druid.stat.JdbcDataSourceStat; import com.alibaba.druid.stat.JdbcSqlStat; @@ -336,7 +342,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat this.id = DruidDriver.createDataSourceId(); loadFilterFromSystemProperty(); - + if (this.dbType == null || this.dbType.length() == 0) { this.dbType = JdbcUtils.getDbType(jdbcUrl, null); } @@ -576,12 +582,74 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat if (driver.getMajorVersion() == 10 && isUseOracleImplicitCache()) { this.getConnectProperties().setProperty("oracle.jdbc.FreeMemoryOnEnterImplicitCache", "true"); } + + oracleValidationQueryCheck(); } else if (JdbcUtils.MYSQL.equals(this.dbType)) { if (!this.isTestWhileIdle()) { if (LOG.isWarnEnabled()) { LOG.warn("Your dbType is mysql, recommend set testWhileIdle is true"); } } + } else if (JdbcUtils.DB2.equals(dbType)) { + db2ValidationQueryCheck(); + } + } + + private void oracleValidationQueryCheck() { + if (validationQuery == null) { + return; + } + if (validationQuery.length() == 0) { + return; + } + + SQLStatementParser sqlStmtParser = SQLParserUtils.createSQLStatementParser(validationQuery, this.dbType); + List stmtList = sqlStmtParser.parseStatementList(); + + if (stmtList.size() != 1) { + return; + } + + SQLStatement stmt = stmtList.get(0); + if (!(stmt instanceof SQLSelectStatement)) { + return; + } + + SQLSelectQuery query = ((SQLSelectStatement) stmt).getSelect().getQuery(); + if (query instanceof SQLSelectQueryBlock) { + if (((SQLSelectQueryBlock) query).getFrom() == null) { + LOG.error("invalid oracle validationQuery. " + validationQuery + ", may should be : " + validationQuery + + " FROM DUAL"); + } + } + } + + private void db2ValidationQueryCheck() { + if (validationQuery == null) { + return; + } + if (validationQuery.length() == 0) { + return; + } + + SQLStatementParser sqlStmtParser = SQLParserUtils.createSQLStatementParser(validationQuery, this.dbType); + List stmtList = sqlStmtParser.parseStatementList(); + + if (stmtList.size() != 1) { + return; + } + + SQLStatement stmt = stmtList.get(0); + if (!(stmt instanceof SQLSelectStatement)) { + return; + } + + SQLSelectQuery query = ((SQLSelectStatement) stmt).getSelect().getQuery(); + if (query instanceof SQLSelectQueryBlock) { + if (((SQLSelectQueryBlock) query).getFrom() == null) { + LOG.error("invalid db2 validationQuery. " + validationQuery + ", may should be : " + validationQuery + + " FROM SYSDUMMY"); + } } } @@ -710,7 +778,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat try { activeCount--; discardCount++; - + if (activeCount <= 0) { empty.signal(); } diff --git a/src/test/java/com/alibaba/druid/bvt/pool/ValidationQueryLogDB2Test.java b/src/test/java/com/alibaba/druid/bvt/pool/ValidationQueryLogDB2Test.java new file mode 100644 index 0000000000..7f4b1cc0b9 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/ValidationQueryLogDB2Test.java @@ -0,0 +1,44 @@ +package com.alibaba.druid.bvt.pool; + +import java.lang.reflect.Field; +import java.sql.Connection; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import com.alibaba.druid.mock.MockDriver; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.support.logging.Log; +import com.alibaba.druid.util.JdbcConstants; + +public class ValidationQueryLogDB2Test extends TestCase { + + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + dataSource.setUrl("jdbc:mock:xxx"); + dataSource.setDbType(JdbcConstants.DB2); + dataSource.setDriver(new MockDriver() { + public int getMajorVersion() { + return 10; + } + }); + dataSource.setValidationQuery("SELECT 'x'"); + } + + protected void tearDown() throws Exception { + dataSource.close(); + } + + public void test_oracle() throws Exception { + Connection conn = dataSource.getConnection(); + + conn.close(); + + Field field = DruidDataSource.class.getDeclaredField("LOG"); + field.setAccessible(true); + Log log = (Log) field.get(null); + Assert.assertEquals(1, log.getErrorCount()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/pool/ValidationQueryLogTest.java b/src/test/java/com/alibaba/druid/bvt/pool/ValidationQueryLogTest.java new file mode 100644 index 0000000000..4e9c348835 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/pool/ValidationQueryLogTest.java @@ -0,0 +1,44 @@ +package com.alibaba.druid.bvt.pool; + +import java.lang.reflect.Field; +import java.sql.Connection; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import com.alibaba.druid.mock.MockDriver; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.support.logging.Log; +import com.alibaba.druid.util.JdbcConstants; + +public class ValidationQueryLogTest extends TestCase { + + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + dataSource.setUrl("jdbc:mock:xxx"); + dataSource.setDbType(JdbcConstants.ORACLE); + dataSource.setDriver(new MockDriver() { + public int getMajorVersion() { + return 10; + } + }); + dataSource.setValidationQuery("SELECT 'x'"); + } + + protected void tearDown() throws Exception { + dataSource.close(); + } + + public void test_oracle() throws Exception { + Connection conn = dataSource.getConnection(); + + conn.close(); + + Field field = DruidDataSource.class.getDeclaredField("LOG"); + field.setAccessible(true); + Log log = (Log) field.get(null); + Assert.assertEquals(1, log.getErrorCount()); + } +}