]> source.dussan.org Git - sonarqube.git/commitdiff
SONARCLOUD-161 add Dialect#supportsUpsert(), true only on postgreSQL
authorSimon Brandhof <simon.brandhof@sonarsource.com>
Sun, 28 Oct 2018 22:16:26 +0000 (23:16 +0100)
committerSonarTech <sonartech@sonarsource.com>
Tue, 30 Oct 2018 19:21:25 +0000 (20:21 +0100)
server/sonar-db-core/src/main/java/org/sonar/db/dialect/AbstractDialect.java
server/sonar-db-core/src/main/java/org/sonar/db/dialect/Dialect.java
server/sonar-db-core/src/main/java/org/sonar/db/dialect/PostgreSql.java
server/sonar-db-core/src/test/java/org/sonar/db/dialect/H2Test.java
server/sonar-db-core/src/test/java/org/sonar/db/dialect/MsSqlTest.java
server/sonar-db-core/src/test/java/org/sonar/db/dialect/MySqlTest.java
server/sonar-db-core/src/test/java/org/sonar/db/dialect/OracleTest.java
server/sonar-db-core/src/test/java/org/sonar/db/dialect/PostgreSqlTest.java

index f4f738aa5de2b8414fb6d0797381ea61950c5b71..0959ff1c390d6379233a631d12862e3e40f347fb 100644 (file)
@@ -87,6 +87,11 @@ abstract class AbstractDialect implements Dialect {
     return 1;
   }
 
+  @Override
+  public boolean supportsUpsert() {
+    return false;
+  }
+
   Version checkDbVersion(DatabaseMetaData metaData, Version minSupported) throws SQLException {
     int major = metaData.getDatabaseMajorVersion();
     int minor = metaData.getDatabaseMinorVersion();
index 42278d51111e6538e7e264e8caf30057e6e53bf2..44ad59239cdcfd89e95c19316aadb56054e117d9 100644 (file)
@@ -64,6 +64,8 @@ public interface Dialect {
    */
   boolean supportsMigration();
 
+  boolean supportsUpsert();
+
   /**
    * This method is called when connecting for the first
    * time to the database.
index f80169aef21cee05b579720428e22f41b5210b50..5613e13fc83a10b7d525a42023215faa4f50e760 100644 (file)
@@ -25,12 +25,19 @@ import java.sql.SQLException;
 import java.util.List;
 import org.apache.commons.lang.StringUtils;
 import org.sonar.api.utils.Version;
+import org.sonar.api.utils.log.Loggers;
+
+import static com.google.common.base.Preconditions.checkState;
 
 public class PostgreSql extends AbstractDialect {
 
   public static final String ID = "postgresql";
   static final List<String> INIT_STATEMENTS = ImmutableList.of("SET standard_conforming_strings=on", "SET backslash_quote=off");
   private static final Version MIN_SUPPORTED_VERSION = Version.create(9, 3, 0);
+  private static final Version MIN_UPSERT_VERSION = Version.create(9, 5, 0);
+
+  private boolean initialized = false;
+  private boolean supportsUpsert = false;
 
   public PostgreSql() {
     super(ID, "org.postgresql.Driver", "true", "false", "SELECT 1");
@@ -51,8 +58,23 @@ public class PostgreSql extends AbstractDialect {
     return true;
   }
 
+  @Override
+  public boolean supportsUpsert() {
+    checkState(initialized, "onInit() must be called before calling supportsUpsert()");
+    return supportsUpsert;
+  }
+
   @Override
   public void init(DatabaseMetaData metaData) throws SQLException {
-    checkDbVersion(metaData, MIN_SUPPORTED_VERSION);
+    checkState(!initialized, "onInit() must be called once");
+
+    Version version = checkDbVersion(metaData, MIN_SUPPORTED_VERSION);
+
+    supportsUpsert = version.compareTo(MIN_UPSERT_VERSION) >= 0;
+    if (!supportsUpsert) {
+      Loggers.get(getClass()).warn("Upgrading PostgreSQL to {} or greater is recommended for better performances", MIN_UPSERT_VERSION);
+    }
+
+    initialized = true;
   }
 }
index b208e97e984d31a500c6c2863577b323a5f5c8cf..246739ae3d6ddd8b4adb5f0baf7adb5034abfb89 100644 (file)
@@ -75,4 +75,9 @@ public class H2Test {
 
     assertThat(logs.logs(LoggerLevel.WARN)).contains("H2 database should be used for evaluation purpose only.");
   }
+
+  @Test
+  public void supportsUpsert_returns_false() {
+    assertThat(underTest.supportsUpsert()).isFalse();
+  }
 }
index ba4a9a5836f961a7c627d7b6716a935fc1343311..973520d7f4b5aa237a5094e49e0accfa9436bd3e 100644 (file)
@@ -90,6 +90,11 @@ public class MsSqlTest {
     underTest.init(metadata);
   }
 
+  @Test
+  public void supportsUpsert_returns_false() {
+    assertThat(underTest.supportsUpsert()).isFalse();
+  }
+
   private DatabaseMetaData newMetadata(int dbMajorVersion, int dbMinorVersion) throws SQLException {
     DatabaseMetaData metadata = mock(DatabaseMetaData.class, Mockito.RETURNS_DEEP_STUBS);
     when(metadata.getDatabaseMajorVersion()).thenReturn(dbMajorVersion);
index de15828f258ec4ea59f3853f9afe48dd87436728..e6d80631dbeb516c4155e2d441690b839f82b7c5 100644 (file)
@@ -102,6 +102,11 @@ public class MySqlTest {
     assertThat(logs.logs(LoggerLevel.WARN)).contains("MySQL support is deprecated and will be dropped soon.");
   }
 
+  @Test
+  public void supportsUpsert_returns_false() {
+    assertThat(underTest.supportsUpsert()).isFalse();
+  }
+
   private DatabaseMetaData newMetadata(int dbMajorVersion, int dbMinorVersion) throws SQLException {
     DatabaseMetaData metadata = mock(DatabaseMetaData.class, Mockito.RETURNS_DEEP_STUBS);
     when(metadata.getDatabaseMajorVersion()).thenReturn(dbMajorVersion);
index e0725a0d0a0ea196fe1be4c485ff5717308f2012..2eb3564b20f62a63413b888137cb528c6c2197f6 100644 (file)
@@ -131,6 +131,11 @@ public class OracleTest {
     }
   }
 
+  @Test
+  public void supportsUpsert_returns_false() {
+    assertThat(underTest.supportsUpsert()).isFalse();
+  }
+
   private DatabaseMetaData newMetadata(int dbMajorVersion, int dbMinorVersion, String driverVersion) throws SQLException {
     DatabaseMetaData metadata = mock(DatabaseMetaData.class, Mockito.RETURNS_DEEP_STUBS);
     when(metadata.getDatabaseMajorVersion()).thenReturn(dbMajorVersion);
index 3e1b7b065a41f12095cdb1f366b76b45804722c9..d911c5dce8e7cf1051d3980b585d00ac9eb89987 100644 (file)
@@ -26,6 +26,8 @@ import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.mockito.Mockito;
 import org.sonar.api.utils.MessageException;
+import org.sonar.api.utils.log.LogTester;
+import org.sonar.api.utils.log.LoggerLevel;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
@@ -35,6 +37,8 @@ public class PostgreSqlTest {
 
   @Rule
   public ExpectedException expectedException = ExpectedException.none();
+  @Rule
+  public LogTester logs = new LogTester();
 
   private PostgreSql underTest = new PostgreSql();
 
@@ -78,7 +82,7 @@ public class PostgreSqlTest {
   }
 
   @Test
-  public void init_throws_MessageException_if_postgresql_9_2() throws Exception {
+  public void postgresql_9_2_is_not_supported() throws Exception {
     expectedException.expect(MessageException.class);
     expectedException.expectMessage("Unsupported postgresql version: 9.2. Minimal supported version is 9.3.");
 
@@ -87,9 +91,40 @@ public class PostgreSqlTest {
   }
 
   @Test
-  public void init_does_not_fail_if_postgresql_9_3() throws Exception {
+  public void postgresql_9_3_is_supported_without_upsert() throws Exception {
     DatabaseMetaData metadata = newMetadata( 9, 3);
     underTest.init(metadata);
+
+    assertThat(underTest.supportsUpsert()).isFalse();
+    assertThat(logs.logs(LoggerLevel.WARN)).contains("Upgrading PostgreSQL to 9.5 or greater is recommended for better performances");
+  }
+
+  @Test
+  public void postgresql_9_5_is_supported_with_upsert() throws Exception {
+    DatabaseMetaData metadata = newMetadata( 9, 5);
+    underTest.init(metadata);
+
+    assertThat(underTest.supportsUpsert()).isTrue();
+    assertThat(logs.logs(LoggerLevel.WARN)).isEmpty();
+  }
+
+  @Test
+  public void init_throws_ISE_if_called_twice() throws Exception {
+    DatabaseMetaData metaData = newMetadata(9, 5);
+    underTest.init(metaData);
+
+    expectedException.expect(IllegalStateException.class);
+    expectedException.expectMessage("onInit() must be called once");
+
+    underTest.init(metaData);
+  }
+
+  @Test
+  public void supportsUpsert_throws_ISE_if_not_initialized() {
+    expectedException.expect(IllegalStateException.class);
+    expectedException.expectMessage("onInit() must be called before calling supportsUpsert()");
+
+    underTest.supportsUpsert();
   }
 
   private DatabaseMetaData newMetadata(int dbMajorVersion, int dbMinorVersion) throws SQLException {