aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-db
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@sonarsource.com>2016-05-05 10:55:42 +0200
committerSimon Brandhof <simon.brandhof@sonarsource.com>2016-05-05 10:56:09 +0200
commit5e424b6e964cf798e7ecb674b2fff82d5fbebef4 (patch)
treed1455f539ebe84f074a4b4aefc56cbf6de765eaf /sonar-db
parentab6c53bfe803a32c33b5f200e8dbc00f6d912be0 (diff)
downloadsonarqube-5e424b6e964cf798e7ecb674b2fff82d5fbebef4.tar.gz
sonarqube-5e424b6e964cf798e7ecb674b2fff82d5fbebef4.zip
SONAR-7589 Error when upgrading to SonarQube 5.5 on SQL Azure
Diffstat (limited to 'sonar-db')
-rw-r--r--sonar-db/src/main/java/org/sonar/db/charset/ColumnDef.java17
-rw-r--r--sonar-db/src/main/java/org/sonar/db/charset/MssqlCharsetHandler.java3
-rw-r--r--sonar-db/src/main/java/org/sonar/db/charset/MysqlCharsetHandler.java3
-rw-r--r--sonar-db/src/main/java/org/sonar/db/version/DatabaseVersion.java5
-rw-r--r--sonar-db/src/test/java/org/sonar/db/charset/ColumnDefTest.java45
-rw-r--r--sonar-db/src/test/java/org/sonar/db/charset/MssqlCharsetHandlerTest.java11
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);
}