org.sonar.server.platform.db.migration.sql.RenameColumnsBuilderTest.java Source code

Java tutorial

Introduction

Here is the source code for org.sonar.server.platform.db.migration.sql.RenameColumnsBuilderTest.java

Source

/*
 * SonarQube
 * Copyright (C) 2009-2018 SonarSource SA
 * mailto:info 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.server.platform.db.migration.sql;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.text.StrSubstitutor;
import org.junit.Rule;
import org.junit.experimental.theories.DataPoints;
import org.junit.experimental.theories.FromDataPoints;
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
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.server.platform.db.migration.def.BigIntegerColumnDef;
import org.sonar.server.platform.db.migration.def.BlobColumnDef;
import org.sonar.server.platform.db.migration.def.BooleanColumnDef;
import org.sonar.server.platform.db.migration.def.ClobColumnDef;
import org.sonar.server.platform.db.migration.def.ColumnDef;
import org.sonar.server.platform.db.migration.def.DecimalColumnDef;
import org.sonar.server.platform.db.migration.def.IntegerColumnDef;
import org.sonar.server.platform.db.migration.def.TinyIntColumnDef;
import org.sonar.server.platform.db.migration.def.VarcharColumnDef;

import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
import static org.assertj.core.api.Assertions.assertThat;

@RunWith(Theories.class)
public class RenameColumnsBuilderTest {

    @Rule
    public ExpectedException expectedException = ExpectedException.none();

    private static final String NEW_COLUMN_NAME = "new_" + randomAlphabetic(6).toLowerCase();

    @DataPoints("database")
    public static final DatabaseAndResult[] DATABASES = {
            new DatabaseAndResult(new H2(),
                    "ALTER TABLE ${table_name} ALTER COLUMN ${old_column_name} RENAME TO ${new_column_name}"),
            new DatabaseAndResult(new PostgreSql(),
                    "ALTER TABLE ${table_name} RENAME COLUMN ${old_column_name} TO ${new_column_name}"),
            new DatabaseAndResult(new MySql(),
                    "ALTER TABLE ${table_name} CHANGE ${old_column_name} ${new_column_name} ${column_def}"),
            new DatabaseAndResult(new MsSql(),
                    "EXEC sp_rename '${table_name}.${old_column_name}', '${new_column_name}', 'COLUMN'"),
            new DatabaseAndResult(new Oracle(),
                    "ALTER TABLE ${table_name} RENAME COLUMN ${old_column_name} TO ${new_column_name}") };

    @DataPoints("columnDef")
    public static final ColumnDef[] COLUMN_DEFS = {
            BigIntegerColumnDef.newBigIntegerColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(false)
                    .build(),
            BigIntegerColumnDef.newBigIntegerColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(true)
                    .build(),
            BlobColumnDef.newBlobColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(false).build(),
            BlobColumnDef.newBlobColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(true).build(),
            BooleanColumnDef.newBooleanColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(false)
                    .build(),
            BooleanColumnDef.newBooleanColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(true)
                    .build(),
            ClobColumnDef.newClobColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(false).build(),
            ClobColumnDef.newClobColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(true).build(),
            DecimalColumnDef.newDecimalColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(false)
                    .build(),
            DecimalColumnDef.newDecimalColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(true)
                    .build(),
            IntegerColumnDef.newIntegerColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(false)
                    .build(),
            IntegerColumnDef.newIntegerColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(true)
                    .build(),
            TinyIntColumnDef.newTinyIntColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(false)
                    .build(),
            TinyIntColumnDef.newTinyIntColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(true)
                    .build(),
            VarcharColumnDef.newVarcharColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(false)
                    .setLimit(10).build(),
            VarcharColumnDef.newVarcharColumnDefBuilder().setColumnName(NEW_COLUMN_NAME).setIsNullable(true)
                    .setLimit(10).build(), };

    @DataPoints("illegalColumnName")
    public static final String[] ILLEGAL_COLUMN_NAME = { "", "AA", "A.A", "_A", "1A",
            "\uD801\uDC8B\uD801\uDC8C\uD801\uDC8D" };

    @Theory
    public void checkSQL_results(@FromDataPoints("database") DatabaseAndResult database,
            @FromDataPoints("columnDef") ColumnDef columnDef) {

        String oldColumnName = "old_" + randomAlphabetic(6).toLowerCase();
        String tableName = "table_" + randomAlphabetic(6).toLowerCase();

        List<String> result = new RenameColumnsBuilder(database.getDialect(), tableName)
                .renameColumn(oldColumnName, columnDef).build();

        Map<String, String> parameters = new HashMap<>();
        parameters.put("table_name", tableName);
        parameters.put("old_column_name", oldColumnName);
        parameters.put("new_column_name", NEW_COLUMN_NAME);
        parameters.put("column_def", columnDef.generateSqlType(database.getDialect()));
        String expectedResult = StrSubstitutor.replace(database.getTemplateSql(), parameters);
        assertThat(result).containsExactlyInAnyOrder(expectedResult);
    }

    @Theory
    public void when_old_column_is_same_as_new_column_ISA_is_thrown(
            @FromDataPoints("database") DatabaseAndResult database,
            @FromDataPoints("columnDef") ColumnDef columnDef) {

        String tableName = "table_" + randomAlphabetic(6).toLowerCase();

        expectedException.expect(IllegalArgumentException.class);
        expectedException.expectMessage("Column names must be different");

        new RenameColumnsBuilder(database.getDialect(), tableName).renameColumn(NEW_COLUMN_NAME, columnDef).build();
    }

    @Theory
    public void when_new_column_contains_illegal_character_ISA_is_thrown(
            @FromDataPoints("database") DatabaseAndResult database,
            @FromDataPoints("columnDef") ColumnDef columnDef,
            @FromDataPoints("illegalColumnName") String illegalColumnName) {

        String tableName = "table_" + randomAlphabetic(6).toLowerCase();

        expectedException.expect(IllegalArgumentException.class);

        new RenameColumnsBuilder(database.getDialect(), tableName).renameColumn(illegalColumnName, columnDef)
                .build();
    }

    private static class DatabaseAndResult {
        private final Dialect dialect;
        private final String templateSql;

        private DatabaseAndResult(Dialect dialect, String templateSql) {
            this.dialect = dialect;
            this.templateSql = templateSql;
        }

        public Dialect getDialect() {
            return dialect;
        }

        public String getTemplateSql() {
            return templateSql;
        }
    }
}