]> source.dussan.org Git - sonarqube.git/commitdiff
Use the underlying connection to determine schema
authorEric Hartmann <hartmann.eric@gmail.com>
Wed, 29 Aug 2018 17:05:01 +0000 (19:05 +0200)
committerSonarTech <sonartech@sonarsource.com>
Fri, 7 Sep 2018 18:20:56 +0000 (20:20 +0200)
server/sonar-db-core/src/main/java/org/sonar/db/DatabaseUtils.java
server/sonar-db-core/src/main/java/org/sonar/db/DefaultDatabase.java
server/sonar-db-core/src/test/java/org/sonar/db/DatabaseUtilsTest.java

index eaca483020badf4777273e55140cd858d5147687..79ba984c3fea7a907ff6a45f602b5f46cfce3efa 100644 (file)
@@ -317,21 +317,21 @@ public class DatabaseUtils {
   }
 
   private static boolean doTableExists(String table, Connection connection) {
+    String schema = null;
+
+    try {
+      // Using H2 with a JDBC TCP connection is throwing an exception
+      // See org.h2.engine.SessionRemote#getCurrentSchemaName()
+      if (!"H2 JDBC Driver".equals(connection.getMetaData().getDriverName())) {
+        schema = connection.getSchema();
+      }
+    } catch (SQLException e) {
+      Loggers.get(DatabaseUtils.class).warn("Fail to determine schema. Keeping it null for searching tables", e);
+    }
+
     // table type is used to speed-up Oracle by removing introspection of system tables and aliases.
-    try (ResultSet rs = connection.getMetaData().getTables(connection.getCatalog(), connection.getSchema(), table, TABLE_TYPE)) {
-      System.out.println("****>> " + rs.getMetaData().getSchemaName(1));
-      System.out.println("****>>> " + connection.getSchema());
+    try (ResultSet rs = connection.getMetaData().getTables(connection.getCatalog(), schema, table, TABLE_TYPE)) {
       while (rs.next()) {
-        System.out.println("TABLE_CAT = " + rs.getString("TABLE_CAT"));
-        System.out.println("TABLE_SCHEM = " + rs.getString("TABLE_SCHEM"));
-        System.out.println("TABLE_NAME = " + rs.getString("TABLE_NAME"));
-        System.out.println("TABLE_TYPE = " + rs.getString("TABLE_TYPE"));
-        System.out.println("REMARKS = " + rs.getString("REMARKS"));
-        //System.out.println("TYPE_CAT = " + rs.getString("TYPE_CAT"));
-        //System.out.println("TYPE_SCHEM = " + rs.getString("TYPE_SCHEM"));
-        //System.out.println("TYPE_NAME = " + rs.getString("TYPE_NAME"));
-        System.out.println("SELF_REFERENCING_COL_NAME = " + rs.getString("SELF_REFERENCING_COL_NAME"));
-        System.out.println("REF_GENERATION = " + rs.getString("REF_GENERATION"));
         String name = rs.getString("TABLE_NAME");
         if (table.equalsIgnoreCase(name)) {
           return true;
index 90ad11a5789b8bfa3563af824f9570e679490299..59d8541fccc3de4a24fda46725ebf62d4b4bb4a1 100644 (file)
@@ -93,7 +93,7 @@ public class DefaultDatabase implements Database {
   private void initDataSource() throws Exception {
     // but it's correctly caught by start()
     LOG.info("Create JDBC data source for {}", properties.getProperty(JDBC_URL.getKey()), DEFAULT_URL);
-    BasicDataSource basicDataSource = (BasicDataSource) BasicDataSourceFactory.createDataSource(extractCommonsDbcpProperties(properties));
+    BasicDataSource basicDataSource = BasicDataSourceFactory.createDataSource(extractCommonsDbcpProperties(properties));
     datasource = new ProfiledDataSource(basicDataSource, NullConnectionInterceptor.INSTANCE);
     datasource.setConnectionInitSqls(dialect.getConnectionInitStatements());
     datasource.setValidationQuery(dialect.getValidationQuery());
@@ -163,6 +163,7 @@ public class DefaultDatabase implements Database {
   @VisibleForTesting
   static Properties extractCommonsDbcpProperties(Properties properties) {
     Properties result = new Properties();
+    result.setProperty("accessToUnderlyingConnectionAllowed", "true");
     for (Map.Entry<Object, Object> entry : properties.entrySet()) {
       String key = (String) entry.getKey();
       if (StringUtils.startsWith(key, SONAR_JDBC)) {
index fef76f8680e9852563053f1a4bb3109819853ba5..c0f34ea752cc6bfb0c8a8df9d957d7fd9b0f2f18 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.db;
 
 import com.google.common.base.Function;
 import java.sql.Connection;
+import java.sql.DatabaseMetaData;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
@@ -44,9 +45,15 @@ import static com.google.common.collect.Lists.newArrayList;
 import static java.util.Arrays.asList;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.fail;
+import static org.mockito.Answers.CALLS_REAL_METHODS;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 import static org.sonar.db.DatabaseUtils.toUniqueAndSortedList;
 
 public class DatabaseUtilsTest {
@@ -333,6 +340,38 @@ public class DatabaseUtilsTest {
     }
   }
 
+  @Test
+  public void tableExists_is_resilient_on_getSchema() throws Exception {
+    try (Connection connection = spy(dbTester.openConnection())) {
+      doThrow(AbstractMethodError.class).when(connection).getSchema();
+      assertThat(DatabaseUtils.tableExists("SCHEMA_MIGRATIONS", connection)).isTrue();
+      assertThat(DatabaseUtils.tableExists("schema_migrations", connection)).isTrue();
+      assertThat(DatabaseUtils.tableExists("schema_MIGRATIONS", connection)).isTrue();
+      assertThat(DatabaseUtils.tableExists("foo", connection)).isFalse();
+    }
+  }
+
+  @Test
+  public void tableExists_is_using_getSchema_when_not_using_h2() throws Exception {
+    try (Connection connection = spy(dbTester.openConnection())) {
+      // DatabaseMetaData mock
+      DatabaseMetaData metaData = mock(DatabaseMetaData.class);
+      doReturn("xxx").when(metaData).getDriverName();
+
+      // ResultSet mock
+      ResultSet resultSet = mock(ResultSet.class);
+      doReturn(true, false).when(resultSet).next();
+      doReturn("SCHEMA_MIGRATIONS").when(resultSet).getString(eq("TABLE_NAME"));
+      doReturn(resultSet).when(metaData).getTables(any(), eq("yyyy"), any(), any());
+
+      // Connection mock
+      doReturn("yyyy").when(connection).getSchema();
+      doReturn(metaData).when(connection).getMetaData();
+
+      assertThat(DatabaseUtils.tableExists("SCHEMA_MIGRATIONS", connection)).isTrue();
+    }
+  }
+
   @Test
   public void checkThatNotTooManyConditions_does_not_fail_if_less_than_1000_conditions() {
     DatabaseUtils.checkThatNotTooManyConditions(null, "unused");