*/
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;
}
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:
}
}
- 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;
- }
- }
}
--- /dev/null
+/*
+ * 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);
+ }
+ }
+
+}
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;
/**
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();
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 :
private String generateSql() {
return new AddColumnsBuilder(getDatabase().getDialect(), "manual_measures")
.addColumn(
- new AddColumnsBuilder.ColumnDef()
+ new ColumnDef()
.setName("component_uuid")
.setType(STRING)
.setLimit(50)
*/
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));
}
}
--- /dev/null
+/*
+ * 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);
+ }
+}