diff options
author | Simon Brandhof <simon.brandhof@sonarsource.com> | 2016-05-05 10:55:42 +0200 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@sonarsource.com> | 2016-05-05 10:56:09 +0200 |
commit | 5e424b6e964cf798e7ecb674b2fff82d5fbebef4 (patch) | |
tree | d1455f539ebe84f074a4b4aefc56cbf6de765eaf /sonar-db | |
parent | ab6c53bfe803a32c33b5f200e8dbc00f6d912be0 (diff) | |
download | sonarqube-5e424b6e964cf798e7ecb674b2fff82d5fbebef4.tar.gz sonarqube-5e424b6e964cf798e7ecb674b2fff82d5fbebef4.zip |
SONAR-7589 Error when upgrading to SonarQube 5.5 on SQL Azure
Diffstat (limited to 'sonar-db')
6 files changed, 80 insertions, 4 deletions
diff --git a/sonar-db/src/main/java/org/sonar/db/charset/ColumnDef.java b/sonar-db/src/main/java/org/sonar/db/charset/ColumnDef.java index 45d4b017546..461bf32365b 100644 --- a/sonar-db/src/main/java/org/sonar/db/charset/ColumnDef.java +++ b/sonar-db/src/main/java/org/sonar/db/charset/ColumnDef.java @@ -19,9 +19,13 @@ */ package org.sonar.db.charset; +import com.google.common.base.Predicate; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.Locale; +import javax.annotation.Nonnull; import javax.annotation.concurrent.Immutable; +import org.sonar.db.version.DatabaseVersion; /** * Result of standard SQL command "select * from INFORMATION_SCHEMA" (columns listed in {@link #SELECT_COLUMNS}). @@ -77,6 +81,10 @@ public class ColumnDef { return nullable; } + public boolean isInSonarQubeTable() { + return DatabaseVersion.TABLES.contains(table.toLowerCase(Locale.ENGLISH)); + } + public enum ColumnDefRowConverter implements SqlExecutor.RowConverter<ColumnDef> { INSTANCE; @@ -89,4 +97,13 @@ public class ColumnDef { rs.getString(1), rs.getString(2), rs.getString(3), rs.getString(4), rs.getString(5), rs.getLong(6), nullable); } } + + public enum IsInSonarQubeTablePredicate implements Predicate<ColumnDef> { + INSTANCE; + + @Override + public boolean apply(@Nonnull ColumnDef input) { + return input.isInSonarQubeTable(); + } + } } diff --git a/sonar-db/src/main/java/org/sonar/db/charset/MssqlCharsetHandler.java b/sonar-db/src/main/java/org/sonar/db/charset/MssqlCharsetHandler.java index 347fc372133..774251771eb 100644 --- a/sonar-db/src/main/java/org/sonar/db/charset/MssqlCharsetHandler.java +++ b/sonar-db/src/main/java/org/sonar/db/charset/MssqlCharsetHandler.java @@ -27,6 +27,7 @@ import java.util.List; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; +import static com.google.common.collect.FluentIterable.from; import static java.lang.String.format; import static org.apache.commons.lang.StringUtils.endsWithIgnoreCase; @@ -53,7 +54,7 @@ class MssqlCharsetHandler extends CharsetHandler { "FROM [INFORMATION_SCHEMA].[COLUMNS] " + "WHERE collation_name is not null " + "ORDER BY table_name,column_name", ColumnDef.ColumnDefRowConverter.INSTANCE); - for (ColumnDef column : columns) { + for (ColumnDef column : from(columns).filter(ColumnDef.IsInSonarQubeTablePredicate.INSTANCE)) { if (!endsWithIgnoreCase(column.getCollation(), "_CS_AS")) { repairColumnCollation(connection, column); } diff --git a/sonar-db/src/main/java/org/sonar/db/charset/MysqlCharsetHandler.java b/sonar-db/src/main/java/org/sonar/db/charset/MysqlCharsetHandler.java index 43ffd828cbe..43bec2d9ffc 100644 --- a/sonar-db/src/main/java/org/sonar/db/charset/MysqlCharsetHandler.java +++ b/sonar-db/src/main/java/org/sonar/db/charset/MysqlCharsetHandler.java @@ -30,6 +30,7 @@ import org.sonar.api.utils.MessageException; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; +import static com.google.common.collect.FluentIterable.from; import static java.lang.String.format; import static org.apache.commons.lang.StringUtils.containsIgnoreCase; import static org.apache.commons.lang.StringUtils.endsWithIgnoreCase; @@ -66,7 +67,7 @@ class MysqlCharsetHandler extends CharsetHandler { "FROM INFORMATION_SCHEMA.columns " + "WHERE table_schema=database() and character_set_name is not null and collation_name is not null", ColumnDef.ColumnDefRowConverter.INSTANCE); List<String> utf8Errors = new ArrayList<>(); - for (ColumnDef column : columns) { + for (ColumnDef column : from(columns).filter(ColumnDef.IsInSonarQubeTablePredicate.INSTANCE)) { if (enforceUtf8 && !containsIgnoreCase(column.getCharset(), UTF8)) { utf8Errors.add(format("%s.%s", column.getTable(), column.getColumn())); } else if (endsWithIgnoreCase(column.getCollation(), "_ci")) { diff --git a/sonar-db/src/main/java/org/sonar/db/version/DatabaseVersion.java b/sonar-db/src/main/java/org/sonar/db/version/DatabaseVersion.java index 8f51cc19382..9ccbc32b410 100644 --- a/sonar-db/src/main/java/org/sonar/db/version/DatabaseVersion.java +++ b/sonar-db/src/main/java/org/sonar/db/version/DatabaseVersion.java @@ -20,9 +20,10 @@ package org.sonar.db.version; import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; import java.util.Collections; import java.util.List; +import java.util.Set; import javax.annotation.Nullable; import org.apache.ibatis.session.SqlSession; import org.sonar.db.MyBatis; @@ -43,7 +44,7 @@ public class DatabaseVersion { * This list is hardcoded because we didn't succeed in using java.sql.DatabaseMetaData#getTables() in the same way * for all the supported databases, particularly due to Oracle results. */ - public static final List<String> TABLES = ImmutableList.of( + public static final Set<String> TABLES = ImmutableSet.of( "active_dashboards", "active_rules", "active_rule_parameters", diff --git a/sonar-db/src/test/java/org/sonar/db/charset/ColumnDefTest.java b/sonar-db/src/test/java/org/sonar/db/charset/ColumnDefTest.java new file mode 100644 index 00000000000..8a718e18b62 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/charset/ColumnDefTest.java @@ -0,0 +1,45 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.db.charset; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ColumnDefTest { + + @Test + public void isInSonarQubeTable_returns_false_if_sqlazure_system_table() { + ColumnDef underTest = new ColumnDef("sys.sysusers", "colum", "charset", "collation", "NVARCHAR", 100L, false); + assertThat(underTest.isInSonarQubeTable()).isFalse(); + + underTest = new ColumnDef("SYS.SYSUSERS", "colum", "charset", "collation", "NVARCHAR", 100L, false); + assertThat(underTest.isInSonarQubeTable()).isFalse(); + } + + @Test + public void isInSonarQubeTable_returns_true_if_table_created_by_sonarqube() { + ColumnDef underTest = new ColumnDef("project_measures", "column", "charset", "collation", "NVARCHAR", 100L, false); + assertThat(underTest.isInSonarQubeTable()).isTrue(); + + underTest = new ColumnDef("PROJECT_MEASURES", "column", "charset", "collation", "NVARCHAR", 100L, false); + assertThat(underTest.isInSonarQubeTable()).isTrue(); + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/charset/MssqlCharsetHandlerTest.java b/sonar-db/src/test/java/org/sonar/db/charset/MssqlCharsetHandlerTest.java index 2712b66b274..f3748576380 100644 --- a/sonar-db/src/test/java/org/sonar/db/charset/MssqlCharsetHandlerTest.java +++ b/sonar-db/src/test/java/org/sonar/db/charset/MssqlCharsetHandlerTest.java @@ -32,6 +32,7 @@ import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -101,6 +102,16 @@ public class MssqlCharsetHandlerTest { verify(selectExecutor).executeUpdate(connection, "ALTER TABLE projects ALTER COLUMN name nvarchar(max) COLLATE Latin1_General_CS_AS NOT NULL"); } + @Test + public void do_not_repair_system_tables_of_sql_azure() throws Exception { + answerColumns(asList(new ColumnDef("sys.sysusers", COLUMN_NAME, "Latin1_General", "Latin1_General_CI_AI", "varchar", 10, false))); + + Connection connection = mock(Connection.class); + underTest.handle(connection, false); + + verify(selectExecutor, never()).executeUpdate(any(Connection.class), anyString()); + } + private void answerColumns(List<ColumnDef> columnDefs) throws SQLException { when(selectExecutor.executeSelect(any(Connection.class), anyString(), eq(ColumnDef.ColumnDefRowConverter.INSTANCE))).thenReturn(columnDefs); } |