From df2dda7678133987ded0d3ab0f29b4cf3139dfec Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Thu, 5 Jan 2017 16:51:42 +0100 Subject: [PATCH] SONAR-8585 configure NLS_SORT param on Oracle client sessions --- .../charset/OracleCharsetHandler.java | 5 ++-- .../charset/OracleCharsetHandlerTest.java | 30 ++++++------------- .../java/org/sonar/db/dialect/Oracle.java | 8 +++++ .../java/org/sonar/db/dialect/OracleTest.java | 24 +++++++-------- 4 files changed, 31 insertions(+), 36 deletions(-) diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/charset/OracleCharsetHandler.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/charset/OracleCharsetHandler.java index 5179d5666b3..9cc6e97416f 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/charset/OracleCharsetHandler.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/charset/OracleCharsetHandler.java @@ -49,9 +49,8 @@ class OracleCharsetHandler extends CharsetHandler { private void expectUtf8(Connection connection) throws SQLException { // Oracle does not allow to override character set on tables. Only global charset is verified. String charset = getSqlExecutor().selectSingleString(connection, "select value from nls_database_parameters where parameter='NLS_CHARACTERSET'"); - String sort = getSqlExecutor().selectSingleString(connection, "select value from nls_database_parameters where parameter='NLS_SORT'"); - if (!containsIgnoreCase(charset, UTF8) || !"BINARY".equalsIgnoreCase(sort)) { - throw MessageException.of(format("Oracle must be have UTF8 charset and BINARY sort. NLS_CHARACTERSET is %s and NLS_SORT is %s.", charset, sort)); + if (!containsIgnoreCase(charset, UTF8)) { + throw MessageException.of(format("Oracle NLS_CHARACTERSET does not support UTF8: %s", charset)); } } } diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/charset/OracleCharsetHandlerTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/charset/OracleCharsetHandlerTest.java index bc0dea3d432..621cc1ec654 100644 --- a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/charset/OracleCharsetHandlerTest.java +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/charset/OracleCharsetHandlerTest.java @@ -22,7 +22,7 @@ package org.sonar.server.platform.db.migration.charset; import java.sql.Connection; import java.sql.SQLException; import java.util.Collections; -import java.util.List; +import javax.annotation.Nullable; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -46,7 +46,7 @@ public class OracleCharsetHandlerTest { @Test public void fresh_install_verifies_utf8_charset() throws Exception { - answerSql(singletonList(new String[] {"UTF8"}), singletonList(new String[] {"BINARY"})); + answerCharset("UTF8"); underTest.handle(connection, DatabaseCharsetChecker.State.FRESH_INSTALL); } @@ -60,37 +60,24 @@ public class OracleCharsetHandlerTest { @Test public void fresh_install_supports_al32utf8() throws Exception { - answerSql( - singletonList(new String[] {"AL32UTF8"}), singletonList(new String[] {"BINARY"})); + answerCharset("AL32UTF8"); underTest.handle(connection, DatabaseCharsetChecker.State.FRESH_INSTALL); } @Test public void fresh_install_fails_if_charset_is_not_utf8() throws Exception { - answerSql( - singletonList(new String[] {"LATIN"}), singletonList(new String[] {"BINARY"})); + answerCharset("LATIN"); expectedException.expect(MessageException.class); - expectedException.expectMessage("Oracle must be have UTF8 charset and BINARY sort. NLS_CHARACTERSET is LATIN and NLS_SORT is BINARY."); - - underTest.handle(connection, DatabaseCharsetChecker.State.FRESH_INSTALL); - } - - @Test - public void fresh_install_fails_if_not_case_sensitive() throws Exception { - answerSql( - singletonList(new String[] {"UTF8"}), singletonList(new String[] {"LINGUISTIC"})); - - expectedException.expect(MessageException.class); - expectedException.expectMessage("Oracle must be have UTF8 charset and BINARY sort. NLS_CHARACTERSET is UTF8 and NLS_SORT is LINGUISTIC."); + expectedException.expectMessage("Oracle NLS_CHARACTERSET does not support UTF8: LATIN"); underTest.handle(connection, DatabaseCharsetChecker.State.FRESH_INSTALL); } @Test public void fails_if_can_not_get_charset() throws Exception { - answerSql(Collections.emptyList(), Collections.emptyList()); + answerCharset(null); expectedException.expect(MessageException.class); @@ -103,7 +90,8 @@ public class OracleCharsetHandlerTest { verifyZeroInteractions(sqlExecutor); } - private void answerSql(List firstRequest, List... otherRequests) throws SQLException { - when(sqlExecutor.select(any(Connection.class), anyString(), any(SqlExecutor.StringsConverter.class))).thenReturn(firstRequest, otherRequests); + private void answerCharset(@Nullable String charset) throws SQLException { + when(sqlExecutor.select(any(Connection.class), anyString(), any(SqlExecutor.StringsConverter.class))) + .thenReturn(charset == null ? Collections.emptyList() : singletonList(new String[] {charset})); } } diff --git a/sonar-db/src/main/java/org/sonar/db/dialect/Oracle.java b/sonar-db/src/main/java/org/sonar/db/dialect/Oracle.java index eecd0a758e6..aa7908b2827 100644 --- a/sonar-db/src/main/java/org/sonar/db/dialect/Oracle.java +++ b/sonar-db/src/main/java/org/sonar/db/dialect/Oracle.java @@ -19,6 +19,8 @@ */ package org.sonar.db.dialect; +import com.google.common.collect.ImmutableList; +import java.util.List; import org.apache.commons.lang.StringUtils; /** @@ -27,6 +29,7 @@ import org.apache.commons.lang.StringUtils; public class Oracle extends AbstractDialect { public static final String ID = "oracle"; + private static final List INIT_STATEMENTS = ImmutableList.of("ALTER SESSION SET NLS_SORT='BINARY'"); public Oracle() { super(ID, "oracle", "oracle.jdbc.OracleDriver", "1", "0", "SELECT 1 FROM DUAL"); @@ -41,4 +44,9 @@ public class Oracle extends AbstractDialect { public boolean supportsMigration() { return true; } + + @Override + public List getConnectionInitStatements() { + return INIT_STATEMENTS; + } } diff --git a/sonar-db/src/test/java/org/sonar/db/dialect/OracleTest.java b/sonar-db/src/test/java/org/sonar/db/dialect/OracleTest.java index bea6dd7da1a..04a2ed68893 100644 --- a/sonar-db/src/test/java/org/sonar/db/dialect/OracleTest.java +++ b/sonar-db/src/test/java/org/sonar/db/dialect/OracleTest.java @@ -25,36 +25,36 @@ import static org.assertj.core.api.Assertions.assertThat; public class OracleTest { - Oracle dialect = new Oracle(); + private Oracle underTest = new Oracle(); @Test public void matchesJdbcURL() { - assertThat(dialect.matchesJdbcURL("jdbc:oracle:thin:@localhost/XE")).isTrue(); - assertThat(dialect.matchesJdbcURL("jdbc:hsql:foo")).isFalse(); + assertThat(underTest.matchesJdbcURL("jdbc:oracle:thin:@localhost/XE")).isTrue(); + assertThat(underTest.matchesJdbcURL("jdbc:hsql:foo")).isFalse(); } @Test public void testBooleanSqlValues() { - assertThat(dialect.getTrueSqlValue()).isEqualTo("1"); - assertThat(dialect.getFalseSqlValue()).isEqualTo("0"); + assertThat(underTest.getTrueSqlValue()).isEqualTo("1"); + assertThat(underTest.getFalseSqlValue()).isEqualTo("0"); } @Test public void should_configure() { - assertThat(dialect.getId()).isEqualTo("oracle"); - assertThat(dialect.getActiveRecordDialectCode()).isEqualTo("oracle"); - assertThat(dialect.getDefaultDriverClassName()).isEqualTo("oracle.jdbc.OracleDriver"); - assertThat(dialect.getValidationQuery()).isEqualTo("SELECT 1 FROM DUAL"); + assertThat(underTest.getId()).isEqualTo("oracle"); + assertThat(underTest.getActiveRecordDialectCode()).isEqualTo("oracle"); + assertThat(underTest.getDefaultDriverClassName()).isEqualTo("oracle.jdbc.OracleDriver"); + assertThat(underTest.getValidationQuery()).isEqualTo("SELECT 1 FROM DUAL"); } @Test public void testFetchSizeForScrolling() throws Exception { - assertThat(dialect.getScrollDefaultFetchSize()).isEqualTo(200); - assertThat(dialect.getScrollSingleRowFetchSize()).isEqualTo(1); + assertThat(underTest.getScrollDefaultFetchSize()).isEqualTo(200); + assertThat(underTest.getScrollSingleRowFetchSize()).isEqualTo(1); } @Test public void oracle_does_supportMigration() { - assertThat(dialect.supportsMigration()).isTrue(); + assertThat(underTest.supportsMigration()).isTrue(); } } -- 2.39.5