]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6840 Extract ColumnDef from AddColumnsBuilder
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 17 Sep 2015 12:49:15 +0000 (14:49 +0200)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Fri, 18 Sep 2015 13:31:20 +0000 (15:31 +0200)
And add a check when no column has been defined

sonar-db/src/main/java/org/sonar/db/version/AddColumnsBuilder.java
sonar-db/src/main/java/org/sonar/db/version/ColumnDef.java [new file with mode: 0644]
sonar-db/src/main/java/org/sonar/db/version/v51/AddIssuesColumns.java
sonar-db/src/main/java/org/sonar/db/version/v52/AddManualMeasuresComponentUuidColumn.java
sonar-db/src/test/java/org/sonar/db/version/AddColumnsBuilderTest.java
sonar-db/src/test/java/org/sonar/db/version/ColumnDefTest.java [new file with mode: 0644]

index ab6543fffe7c5f23c4c5be5bdbeb1bb1e202897e..2bfb76535450f5863c766d224d247764cdd31c04 100644 (file)
  */
 package org.sonar.db.version;
 
-import com.google.common.base.CharMatcher;
-import com.google.common.base.Preconditions;
 import java.util.List;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
 import org.sonar.db.dialect.Dialect;
 import org.sonar.db.dialect.MsSql;
 import org.sonar.db.dialect.Oracle;
@@ -48,6 +44,10 @@ public class AddColumnsBuilder {
   }
 
   public String build() {
+    if (columnDefs.isEmpty()) {
+      throw new IllegalStateException("No column has been defined");
+    }
+
     StringBuilder sql = new StringBuilder().append("ALTER TABLE ").append(tableName).append(" ");
     switch (dialect.getId()) {
       case PostgreSql.ID:
@@ -95,52 +95,4 @@ public class AddColumnsBuilder {
     }
   }
 
-  public static class ColumnDef {
-    private String name;
-    private Type type;
-    private boolean isNullable;
-    private Integer limit;
-
-    public enum Type {
-      STRING, BIG_INTEGER
-    }
-
-    public ColumnDef setNullable(boolean isNullable) {
-      this.isNullable = isNullable;
-      return this;
-    }
-
-    public ColumnDef setLimit(@Nullable Integer limit) {
-      this.limit = limit;
-      return this;
-    }
-
-    public ColumnDef setName(String name) {
-      Preconditions.checkArgument(CharMatcher.JAVA_LOWER_CASE.or(CharMatcher.anyOf("_")).matchesAllOf(name), "Column name should only contains lowercase and _ characters");
-      this.name = name;
-      return this;
-    }
-
-    public ColumnDef setType(Type type) {
-      this.type = type;
-      return this;
-    }
-
-    public boolean isNullable() {
-      return isNullable;
-    }
-
-    @CheckForNull
-    public Integer getLimit() {
-      return limit;
-    }
-
-    public String getName() {
-      return name;
-    }
-
-    public Type getType() {
-      return type;
-    }
-  }
 }
diff --git a/sonar-db/src/main/java/org/sonar/db/version/ColumnDef.java b/sonar-db/src/main/java/org/sonar/db/version/ColumnDef.java
new file mode 100644 (file)
index 0000000..a95fba6
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.version;
+
+import com.google.common.base.CharMatcher;
+import com.google.common.base.Preconditions;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import org.sonar.db.dialect.Dialect;
+import org.sonar.db.dialect.Oracle;
+
+public class ColumnDef {
+
+  private String name;
+  private Type type;
+  private boolean isNullable;
+  private Integer limit;
+
+  public enum Type {
+    STRING, BIG_INTEGER
+  }
+
+  public ColumnDef setNullable(boolean isNullable) {
+    this.isNullable = isNullable;
+    return this;
+  }
+
+  public ColumnDef setLimit(@Nullable Integer limit) {
+    this.limit = limit;
+    return this;
+  }
+
+  public ColumnDef setName(String name) {
+    Preconditions.checkArgument(CharMatcher.JAVA_LOWER_CASE.or(CharMatcher.anyOf("_")).matchesAllOf(name), "Column name should only contains lowercase and _ characters");
+    this.name = name;
+    return this;
+  }
+
+  public ColumnDef setType(Type type) {
+    this.type = type;
+    return this;
+  }
+
+  public boolean isNullable() {
+    return isNullable;
+  }
+
+  @CheckForNull
+  public Integer getLimit() {
+    return limit;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public Type getType() {
+    return type;
+  }
+
+  public String getSqlType(Dialect dialect) {
+    switch (type) {
+      case STRING:
+        return "VARCHAR";
+      case BIG_INTEGER:
+        return dialect.getId().equals(Oracle.ID) ? "NUMBER (38)" : "BIGINT";
+      default:
+        throw new IllegalArgumentException("Unsupported type : " + type);
+    }
+  }
+
+}
index 09ffbdb94a8245737da09d45957e8f907ab1d6c0..f8070a7b34c314c266931bc052c2088c3be2b1aa 100644 (file)
@@ -23,6 +23,7 @@ package org.sonar.db.version.v51;
 import java.sql.SQLException;
 import org.sonar.db.Database;
 import org.sonar.db.version.AddColumnsBuilder;
+import org.sonar.db.version.ColumnDef;
 import org.sonar.db.version.DdlChange;
 
 /**
@@ -51,39 +52,39 @@ public class AddIssuesColumns extends DdlChange {
   private String generateSql() {
     return new AddColumnsBuilder(db.getDialect(), "issues")
       .addColumn(
-        new AddColumnsBuilder.ColumnDef()
+        new ColumnDef()
           .setName("issue_creation_date_ms")
-          .setType(AddColumnsBuilder.ColumnDef.Type.BIG_INTEGER)
+          .setType(ColumnDef.Type.BIG_INTEGER)
           .setNullable(true)
       )
       .addColumn(
-        new AddColumnsBuilder.ColumnDef()
+        new ColumnDef()
           .setName("issue_update_date_ms")
-          .setType(AddColumnsBuilder.ColumnDef.Type.BIG_INTEGER)
+          .setType(ColumnDef.Type.BIG_INTEGER)
           .setNullable(true)
       )
       .addColumn(
-        new AddColumnsBuilder.ColumnDef()
+        new ColumnDef()
           .setName("issue_close_date_ms")
-          .setType(AddColumnsBuilder.ColumnDef.Type.BIG_INTEGER)
+          .setType(ColumnDef.Type.BIG_INTEGER)
           .setNullable(true)
       )
       .addColumn(
-        new AddColumnsBuilder.ColumnDef()
+        new ColumnDef()
           .setName("tags")
-          .setType(AddColumnsBuilder.ColumnDef.Type.STRING)
+          .setType(ColumnDef.Type.STRING)
           .setLimit(4000)
           .setNullable(true))
       .addColumn(
-        new AddColumnsBuilder.ColumnDef()
+        new ColumnDef()
           .setName("component_uuid")
-          .setType(AddColumnsBuilder.ColumnDef.Type.STRING)
+          .setType(ColumnDef.Type.STRING)
           .setLimit(50)
           .setNullable(true))
       .addColumn(
-        new AddColumnsBuilder.ColumnDef()
+        new ColumnDef()
           .setName("project_uuid")
-          .setType(AddColumnsBuilder.ColumnDef.Type.STRING)
+          .setType(ColumnDef.Type.STRING)
           .setLimit(50)
           .setNullable(true))
       .build();
index 7a16b8a51542ec68cb24f8de31468bf43d68e343..9f5e23218b01075f39444be72dfcacf0f66ef197 100644 (file)
@@ -23,9 +23,10 @@ package org.sonar.db.version.v52;
 import java.sql.SQLException;
 import org.sonar.db.Database;
 import org.sonar.db.version.AddColumnsBuilder;
+import org.sonar.db.version.ColumnDef;
 import org.sonar.db.version.DdlChange;
 
-import static org.sonar.db.version.AddColumnsBuilder.ColumnDef.Type.STRING;
+import static org.sonar.db.version.ColumnDef.Type.STRING;
 
 /**
  * Add the following column to the manual_measures table :
@@ -45,7 +46,7 @@ public class AddManualMeasuresComponentUuidColumn extends DdlChange {
   private String generateSql() {
     return new AddColumnsBuilder(getDatabase().getDialect(), "manual_measures")
       .addColumn(
-        new AddColumnsBuilder.ColumnDef()
+        new ColumnDef()
           .setName("component_uuid")
           .setType(STRING)
           .setLimit(50)
index e5160243c7fe8bb87c673f3614c616fcccb775e4..58ac7014cd72d5bed6576f5d19a73946e0fa5479 100644 (file)
  */
 package org.sonar.db.version;
 
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.db.dialect.Dialect;
 import org.sonar.db.dialect.H2;
 import org.sonar.db.dialect.MsSql;
 import org.sonar.db.dialect.MySql;
 import org.sonar.db.dialect.Oracle;
 import org.sonar.db.dialect.PostgreSql;
-import org.sonar.db.version.AddColumnsBuilder;
 
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;
+import static org.sonar.db.version.ColumnDef.Type.BIG_INTEGER;
+import static org.sonar.db.version.ColumnDef.Type.STRING;
 
 public class AddColumnsBuilderTest {
 
+  @Rule
+  public ExpectedException thrown = ExpectedException.none();
+
+  static final String TABLE_NAME = "issues";
+
+  static final H2 H2_DIALECT = new H2();
+  static final MySql MYSQL_DIALECT = new MySql();
+  static final Oracle ORACLE_DIALECT = new Oracle();
+  static final PostgreSql POSTGRES_DIALECT = new PostgreSql();
+  static final MsSql MSSQL_DIALECT = new MsSql();
+
   @Test
   public void add_columns_on_h2() {
-    assertThat(new AddColumnsBuilder(new H2(), "issues")
-      .addColumn(new AddColumnsBuilder.ColumnDef()
-        .setName("date_in_ms")
-        .setType(AddColumnsBuilder.ColumnDef.Type.BIG_INTEGER)
-        .setNullable(true))
-      .addColumn(new AddColumnsBuilder.ColumnDef()
-        .setName("name")
-        .setType(AddColumnsBuilder.ColumnDef.Type.STRING)
-        .setNullable(false)
-        .setLimit(10))
-      .build()).isEqualTo("ALTER TABLE issues ADD (date_in_ms BIGINT NULL, name VARCHAR (10) NOT NULL)");
+    assertThat(createSampleBuilder(H2_DIALECT).build())
+      .isEqualTo("ALTER TABLE issues ADD (date_in_ms BIGINT NULL, name VARCHAR (10) NOT NULL)");
   }
 
   @Test
   public void add_columns_on_mysql() {
-    assertThat(new AddColumnsBuilder(new MySql(), "issues")
-      .addColumn(new AddColumnsBuilder.ColumnDef()
-        .setName("date_in_ms")
-        .setType(AddColumnsBuilder.ColumnDef.Type.BIG_INTEGER)
-        .setNullable(true))
-      .addColumn(new AddColumnsBuilder.ColumnDef()
-        .setName("name")
-        .setType(AddColumnsBuilder.ColumnDef.Type.STRING)
-        .setNullable(false)
-        .setLimit(10))
-      .build()).isEqualTo("ALTER TABLE issues ADD (date_in_ms BIGINT NULL, name VARCHAR (10) NOT NULL)");
+    assertThat(createSampleBuilder(MYSQL_DIALECT).build())
+      .isEqualTo("ALTER TABLE issues ADD (date_in_ms BIGINT NULL, name VARCHAR (10) NOT NULL)");
   }
 
   @Test
   public void add_columns_on_oracle() {
-    assertThat(new AddColumnsBuilder(new Oracle(), "issues")
-      .addColumn(new AddColumnsBuilder.ColumnDef()
-        .setName("date_in_ms")
-        .setType(AddColumnsBuilder.ColumnDef.Type.BIG_INTEGER)
-        .setNullable(true))
-      .addColumn(new AddColumnsBuilder.ColumnDef()
-        .setName("name")
-        .setType(AddColumnsBuilder.ColumnDef.Type.STRING)
-        .setNullable(false)
-        .setLimit(10))
-      .build()).isEqualTo("ALTER TABLE issues ADD (date_in_ms NUMBER (38) NULL, name VARCHAR (10) NOT NULL)");
+    assertThat(createSampleBuilder(ORACLE_DIALECT).build())
+      .isEqualTo("ALTER TABLE issues ADD (date_in_ms NUMBER (38) NULL, name VARCHAR (10) NOT NULL)");
   }
 
   @Test
   public void add_columns_on_postgresql() {
-    assertThat(new AddColumnsBuilder(new PostgreSql(), "issues")
-      .addColumn(new AddColumnsBuilder.ColumnDef()
-        .setName("date_in_ms")
-        .setType(AddColumnsBuilder.ColumnDef.Type.BIG_INTEGER)
-        .setNullable(true))
-      .addColumn(new AddColumnsBuilder.ColumnDef()
-        .setName("name")
-        .setType(AddColumnsBuilder.ColumnDef.Type.STRING)
-        .setNullable(false)
-        .setLimit(10))
-      .build()).isEqualTo("ALTER TABLE issues ADD COLUMN date_in_ms BIGINT NULL, ADD COLUMN name VARCHAR (10) NOT NULL");
+    assertThat(createSampleBuilder(POSTGRES_DIALECT).build())
+      .isEqualTo("ALTER TABLE issues ADD COLUMN date_in_ms BIGINT NULL, ADD COLUMN name VARCHAR (10) NOT NULL");
   }
 
   @Test
   public void add_columns_on_mssql() {
-    assertThat(new AddColumnsBuilder(new MsSql(), "issues")
-      .addColumn(new AddColumnsBuilder.ColumnDef()
-        .setName("date_in_ms")
-        .setType(AddColumnsBuilder.ColumnDef.Type.BIG_INTEGER)
-        .setNullable(true))
-      .addColumn(new AddColumnsBuilder.ColumnDef()
-        .setName("name")
-        .setType(AddColumnsBuilder.ColumnDef.Type.STRING)
-        .setNullable(false)
-        .setLimit(10))
-      .build()).isEqualTo("ALTER TABLE issues ADD date_in_ms BIGINT NULL, name VARCHAR (10) NOT NULL");
+    assertThat(createSampleBuilder(MSSQL_DIALECT).build())
+      .isEqualTo("ALTER TABLE issues ADD date_in_ms BIGINT NULL, name VARCHAR (10) NOT NULL");
   }
 
   @Test
-  public void fail_when_column_name_is_in_upper_case() {
-    try {
-      new AddColumnsBuilder.ColumnDef()
-        .setName("DATE_IN_MS")
-        .setType(AddColumnsBuilder.ColumnDef.Type.BIG_INTEGER)
-        .setNullable(true);
-      failBecauseExceptionWasNotThrown(IllegalArgumentException.class);
-    } catch (IllegalArgumentException e) {
-      assertThat(e).hasMessage("Column name should only contains lowercase and _ characters");
-    }
+  public void fail_with_ISE_if_no_column() {
+    thrown.expect(IllegalStateException.class);
+    thrown.expectMessage("No column has been defined");
+
+    new AddColumnsBuilder(H2_DIALECT, TABLE_NAME).build();
   }
 
-  @Test
-  public void fail_when_column_name_contains_invalid_character() {
-    try {
-      new AddColumnsBuilder.ColumnDef()
-        .setName("date-in/ms")
-        .setType(AddColumnsBuilder.ColumnDef.Type.BIG_INTEGER)
-        .setNullable(true);
-      failBecauseExceptionWasNotThrown(IllegalArgumentException.class);
-    } catch (IllegalArgumentException e) {
-      assertThat(e).hasMessage("Column name should only contains lowercase and _ characters");
-    }
+  private AddColumnsBuilder createSampleBuilder(Dialect dialect) {
+    return new AddColumnsBuilder(dialect, TABLE_NAME)
+      .addColumn(new ColumnDef()
+        .setName("date_in_ms")
+        .setType(BIG_INTEGER)
+        .setNullable(true))
+      .addColumn(new ColumnDef()
+        .setName("name")
+        .setType(STRING)
+        .setNullable(false)
+        .setLimit(10));
   }
 
 }
diff --git a/sonar-db/src/test/java/org/sonar/db/version/ColumnDefTest.java b/sonar-db/src/test/java/org/sonar/db/version/ColumnDefTest.java
new file mode 100644 (file)
index 0000000..c018d84
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.version;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.db.dialect.H2;
+import org.sonar.db.dialect.MsSql;
+import org.sonar.db.dialect.MySql;
+import org.sonar.db.dialect.Oracle;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.db.version.ColumnDef.Type.BIG_INTEGER;
+import static org.sonar.db.version.ColumnDef.Type.STRING;
+
+public class ColumnDefTest {
+
+  @Rule
+  public ExpectedException thrown = ExpectedException.none();
+
+  @Test
+  public void create_column_def() throws Exception {
+    ColumnDef def = new ColumnDef()
+      .setName("date_in_ms")
+      .setType(STRING)
+      .setLimit(10)
+      .setNullable(true);
+
+    assertThat(def.getName()).isEqualTo("date_in_ms");
+    assertThat(def.getType()).isEqualTo(STRING);
+    assertThat(def.getLimit()).isEqualTo(10);
+    assertThat(def.isNullable()).isTrue();
+  }
+
+  @Test
+  public void convert_varchar_type_to_sql() throws Exception {
+    assertThat(new ColumnDef().setType(STRING).getSqlType(new H2())).isEqualTo("VARCHAR");
+    assertThat(new ColumnDef().setType(STRING).getSqlType(new Oracle())).isEqualTo("VARCHAR");
+    assertThat(new ColumnDef().setType(STRING).getSqlType(new MsSql())).isEqualTo("VARCHAR");
+    assertThat(new ColumnDef().setType(STRING).getSqlType(new MySql())).isEqualTo("VARCHAR");
+  }
+
+  @Test
+  public void convert_big_integer_type_to_sql() throws Exception {
+    assertThat(new ColumnDef().setType(BIG_INTEGER).getSqlType(new H2())).isEqualTo("BIGINT");
+    assertThat(new ColumnDef().setType(BIG_INTEGER).getSqlType(new Oracle())).isEqualTo("NUMBER (38)");
+    assertThat(new ColumnDef().setType(BIG_INTEGER).getSqlType(new MsSql())).isEqualTo("BIGINT");
+    assertThat(new ColumnDef().setType(BIG_INTEGER).getSqlType(new MySql())).isEqualTo("BIGINT");
+  }
+
+
+  @Test
+  public void fail_when_column_name_is_in_upper_case() {
+    thrown.expect(IllegalArgumentException.class);
+    thrown.expectMessage("Column name should only contains lowercase and _ characters");
+
+    new ColumnDef()
+      .setName("DATE_IN_MS")
+      .setType(BIG_INTEGER)
+      .setNullable(true);
+  }
+
+  @Test
+  public void fail_when_column_name_contains_invalid_character() {
+    thrown.expect(IllegalArgumentException.class);
+    thrown.expectMessage("Column name should only contains lowercase and _ characters");
+
+    new ColumnDef()
+      .setName("date-in/ms")
+      .setType(BIG_INTEGER)
+      .setNullable(true);
+  }
+}