]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7798 support BIN and BIN2 collation on MsSQL 1062/head
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Fri, 24 Jun 2016 16:11:42 +0000 (18:11 +0200)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Mon, 27 Jun 2016 13:52:46 +0000 (15:52 +0200)
sonar-db/src/main/java/org/sonar/db/charset/MssqlCharsetHandler.java
sonar-db/src/test/java/org/sonar/db/charset/MssqlCharsetHandlerTest.java

index 6eb183647965b3417c239afc414af9fe547c239c..6b3cef60d1fa65fb4624a9af3e941a52b38a11a2 100644 (file)
@@ -43,6 +43,8 @@ class MssqlCharsetHandler extends CharsetHandler {
   private static final String CASE_INSENSITIVE_ACCENT_INSENSITIVE = "_CI_AI";
   private static final String CASE_INSENSITIVE_ACCENT_SENSITIVE = "_CI_AS";
   private static final String CASE_SENSITIVE_ACCENT_INSENSITIVE = "_CS_AI";
+  private static final String BIN = "BIN";
+  private static final String BIN2 = "BIN2";
 
   protected MssqlCharsetHandler(SqlExecutor selectExecutor) {
     super(selectExecutor);
@@ -63,7 +65,7 @@ class MssqlCharsetHandler extends CharsetHandler {
         "ORDER BY table_name,column_name",
       ColumnDef.ColumnDefRowConverter.INSTANCE);
     for (ColumnDef column : from(columns).filter(ColumnDef.IsInSonarQubeTablePredicate.INSTANCE)) {
-      if (!containsIgnoreCase(column.getCollation(), CASE_SENSITIVE_ACCENT_SENSITIVE)) {
+      if (!isCollationCorrect(column)) {
         if (flags.contains(AUTO_REPAIR_COLLATION)) {
           repairColumnCollation(connection, column);
         } else {
@@ -78,6 +80,16 @@ class MssqlCharsetHandler extends CharsetHandler {
     }
   }
 
+  /**
+   * Collation is correct if is contains {@link #CASE_SENSITIVE_ACCENT_SENSITIVE} or {@link #BIN} or {@link #BIN2}.
+   */
+  private static boolean isCollationCorrect(ColumnDef column) {
+    String collation = column.getCollation();
+    return containsIgnoreCase(collation, CASE_SENSITIVE_ACCENT_SENSITIVE)
+      || containsIgnoreCase(collation, BIN)
+      || containsIgnoreCase(collation, BIN2);
+  }
+
   private static void logInit(Set<DatabaseCharsetChecker.Flag> flags) {
     if (flags.contains(AUTO_REPAIR_COLLATION)) {
       LOGGER.info("Repair case-insensitive or accent-insensitive database columns");
@@ -136,9 +148,9 @@ class MssqlCharsetHandler extends CharsetHandler {
   }
 
   @VisibleForTesting
-  static String toCaseSensitive(String ciCollation) {
+  static String toCaseSensitive(String collation) {
     // Example: Latin1_General_CI_AI --> Latin1_General_CS_AS or Latin1_General_100_CI_AS_KS_WS --> Latin1_General_100_CS_AS_KS_WS
-    return ciCollation
+    return collation
       .replace(CASE_INSENSITIVE_ACCENT_INSENSITIVE, CASE_SENSITIVE_ACCENT_SENSITIVE)
       .replace(CASE_INSENSITIVE_ACCENT_SENSITIVE, CASE_SENSITIVE_ACCENT_SENSITIVE)
       .replace(CASE_SENSITIVE_ACCENT_INSENSITIVE, CASE_SENSITIVE_ACCENT_SENSITIVE);
index f097436adf0595ac5788f1c8c63b071f466dc0e3..bd81b60afd207d188fe7dcc966a43353aac64d96 100644 (file)
@@ -129,16 +129,12 @@ public class MssqlCharsetHandlerTest {
   @DataProvider
   public static Object[][] combinationsOfCsAsAndSuffix() {
     List<String[]> res = new ArrayList<>();
-    for (String caseSensitivity : Arrays.asList("CS", "CI")) {
-      for (String accentSensitivity : Arrays.asList("AS", "AI")) {
-        if (caseSensitivity.equals("CI") || accentSensitivity.equals("AI")) {
-          for (String suffix : Arrays.asList("", "_KS_WS")) {
-            res.add(new String[] {
-              format("Latin1_General_%s_%s%s", caseSensitivity, accentSensitivity, suffix),
-              format("Latin1_General_CS_AS%s", suffix)
-            });
-          }
-        }
+    for (String sensitivity : Arrays.asList("CI_AI", "CI_AS", "CS_AI")) {
+      for (String suffix : Arrays.asList("", "_KS_WS")) {
+        res.add(new String[] {
+          format("Latin1_General_%s%s", sensitivity, suffix),
+          format("Latin1_General_CS_AS%s", suffix)
+        });
       }
     }
     return res.stream().toArray(Object[][]::new);
@@ -166,6 +162,44 @@ public class MssqlCharsetHandlerTest {
     verify(selectExecutor, never()).executeUpdate(any(Connection.class), anyString());
   }
 
+  @Test
+  @UseDataProvider("combinationOfBinAndSuffix")
+  public void do_not_repair_if_collation_contains_BIN(String collation) throws Exception {
+    answerColumns(asList(new ColumnDef(TABLE_PROJECTS, COLUMN_NAME, "Latin1_General", collation, "varchar", 10, false)));
+
+    Connection connection = mock(Connection.class);
+    underTest.handle(connection, immutableEnumSet(AUTO_REPAIR_COLLATION));
+
+    verify(selectExecutor, never()).executeUpdate(any(Connection.class), anyString());
+  }
+
+  @DataProvider
+  public static Object[][] combinationOfBinAndSuffix() {
+    return Arrays.asList("", "_KS_WS")
+      .stream()
+      .map(suffix -> new String[] {format("Latin1_General_BIN%s", suffix)})
+      .toArray(Object[][]::new);
+  }
+
+  @Test
+  @UseDataProvider("combinationOfBin2AndSuffix")
+  public void do_not_repair_if_collation_contains_BIN2(String collation) throws Exception {
+    answerColumns(asList(new ColumnDef(TABLE_PROJECTS, COLUMN_NAME, "Latin1_General", collation, "varchar", 10, false)));
+
+    Connection connection = mock(Connection.class);
+    underTest.handle(connection, immutableEnumSet(AUTO_REPAIR_COLLATION));
+
+    verify(selectExecutor, never()).executeUpdate(any(Connection.class), anyString());
+  }
+
+  @DataProvider
+  public static Object[][] combinationOfBin2AndSuffix() {
+    return Arrays.asList("", "_KS_WS")
+      .stream()
+      .map(suffix -> new String[] {format("Latin1_General_BIN2%s", suffix)})
+      .toArray(Object[][]::new);
+  }
+
   private void answerColumns(List<ColumnDef> columnDefs) throws SQLException {
     when(selectExecutor.executeSelect(any(Connection.class), anyString(), eq(ColumnDef.ColumnDefRowConverter.INSTANCE))).thenReturn(columnDefs);
   }