@@ -92,7 +92,7 @@ public class AbstractDbTester<T extends TestDb> extends ExternalResource { | |||
public void executeDdl(String ddl) { | |||
try (Connection connection = getConnection(); | |||
Statement stmt = connection.createStatement()) { | |||
Statement stmt = connection.createStatement()) { | |||
stmt.execute(ddl); | |||
} catch (SQLException e) { | |||
throw new IllegalStateException("Failed to execute DDL: " + ddl, e); | |||
@@ -243,8 +243,8 @@ public class AbstractDbTester<T extends TestDb> extends ExternalResource { | |||
public void assertColumnDefinition(String table, String column, int expectedType, @Nullable Integer expectedSize, @Nullable Boolean isNullable) { | |||
try (Connection connection = getConnection(); | |||
PreparedStatement stmt = connection.prepareStatement("select * from " + table); | |||
ResultSet res = stmt.executeQuery()) { | |||
PreparedStatement stmt = connection.prepareStatement("select * from " + table); | |||
ResultSet res = stmt.executeQuery()) { | |||
Integer columnIndex = getColumnIndex(res, column); | |||
if (columnIndex == null) { | |||
fail("The column '" + column + "' does not exist"); | |||
@@ -264,8 +264,8 @@ public class AbstractDbTester<T extends TestDb> extends ExternalResource { | |||
public void assertColumnDoesNotExist(String table, String column) throws SQLException { | |||
try (Connection connection = getConnection(); | |||
PreparedStatement stmt = connection.prepareStatement("select * from " + table); | |||
ResultSet res = stmt.executeQuery()) { | |||
PreparedStatement stmt = connection.prepareStatement("select * from " + table); | |||
ResultSet res = stmt.executeQuery()) { | |||
assertThat(getColumnNames(res)).doesNotContain(column); | |||
} | |||
} | |||
@@ -303,7 +303,7 @@ public class AbstractDbTester<T extends TestDb> extends ExternalResource { | |||
private void assertIndexImpl(String tableName, String indexName, boolean expectedUnique, String expectedColumn, String... expectedSecondaryColumns) { | |||
try (Connection connection = getConnection(); | |||
ResultSet rs = connection.getMetaData().getIndexInfo(null, null, tableName.toUpperCase(Locale.ENGLISH), false, false)) { | |||
ResultSet rs = connection.getMetaData().getIndexInfo(null, null, tableName.toUpperCase(Locale.ENGLISH), false, false)) { | |||
List<String> onColumns = new ArrayList<>(); | |||
while (rs.next()) { | |||
if (indexName.equalsIgnoreCase(rs.getString("INDEX_NAME"))) { | |||
@@ -312,7 +312,7 @@ public class AbstractDbTester<T extends TestDb> extends ExternalResource { | |||
onColumns.add(position - 1, rs.getString("COLUMN_NAME").toLowerCase(Locale.ENGLISH)); | |||
} | |||
} | |||
assertThat(asList(expectedColumn, expectedSecondaryColumns)).isEqualTo(onColumns); | |||
assertThat(onColumns).containsExactlyInAnyOrderElementsOf(asList(expectedColumn, expectedSecondaryColumns)); | |||
} catch (SQLException e) { | |||
throw new IllegalStateException("Fail to check index", e); | |||
} | |||
@@ -323,7 +323,7 @@ public class AbstractDbTester<T extends TestDb> extends ExternalResource { | |||
*/ | |||
public void assertIndexDoesNotExist(String tableName, String indexName) { | |||
try (Connection connection = getConnection(); | |||
ResultSet rs = connection.getMetaData().getIndexInfo(null, null, tableName.toUpperCase(Locale.ENGLISH), false, false)) { | |||
ResultSet rs = connection.getMetaData().getIndexInfo(null, null, tableName.toUpperCase(Locale.ENGLISH), false, false)) { | |||
List<String> indices = new ArrayList<>(); | |||
while (rs.next()) { | |||
indices.add(rs.getString("INDEX_NAME").toLowerCase(Locale.ENGLISH)); | |||
@@ -398,7 +398,9 @@ public class AbstractDbTester<T extends TestDb> extends ExternalResource { | |||
private static final class PkColumn { | |||
private static final Ordering<PkColumn> ORDERING_BY_INDEX = Ordering.natural().onResultOf(PkColumn::getIndex); | |||
/** 0-based */ | |||
/** | |||
* 0-based | |||
*/ | |||
private final int index; | |||
private final String name; | |||
@@ -422,7 +424,7 @@ public class AbstractDbTester<T extends TestDb> extends ExternalResource { | |||
ResultSetMetaData meta = res.getMetaData(); | |||
int numCol = meta.getColumnCount(); | |||
for (int i = 1; i < numCol + 1; i++) { | |||
if (meta.getColumnLabel(i).toLowerCase().equals(column.toLowerCase())) { | |||
if (meta.getColumnLabel(i).equalsIgnoreCase(column)) { | |||
return i; | |||
} | |||
} |
@@ -812,10 +812,12 @@ CREATE TABLE "RULE_DESC_SECTIONS"( | |||
"UUID" CHARACTER VARYING(40) NOT NULL, | |||
"RULE_UUID" CHARACTER VARYING(40) NOT NULL, | |||
"KEE" CHARACTER VARYING(50) NOT NULL, | |||
"CONTENT" CHARACTER LARGE OBJECT NOT NULL | |||
"CONTENT" CHARACTER LARGE OBJECT NOT NULL, | |||
"CONTEXT_KEY" CHARACTER VARYING(50), | |||
"CONTEXT_DISPLAY_NAME" CHARACTER VARYING(50) | |||
); | |||
ALTER TABLE "RULE_DESC_SECTIONS" ADD CONSTRAINT "PK_RULE_DESC_SECTIONS" PRIMARY KEY("UUID"); | |||
CREATE UNIQUE INDEX "UNIQ_RULE_DESC_SECTIONS_KEE" ON "RULE_DESC_SECTIONS"("RULE_UUID" NULLS FIRST, "KEE" NULLS FIRST); | |||
CREATE UNIQUE INDEX "UNIQ_RULE_DESC_SECTIONS" ON "RULE_DESC_SECTIONS"("RULE_UUID" NULLS FIRST, "KEE" NULLS FIRST, "CONTEXT_KEY" NULLS FIRST); | |||
CREATE TABLE "RULE_REPOSITORIES"( | |||
"KEE" CHARACTER VARYING(200) NOT NULL, |
@@ -66,7 +66,7 @@ public class CreateInitialSchema extends DdlChange { | |||
private static final String LANGUAGE_COL_NAME = "language"; | |||
private static final String METRIC_UUID_COL_NAME = "metric_uuid"; | |||
private static final String PROJECT_UUID_COL_NAME = "project_uuid"; | |||
private static final String RULE_UUID_COL_NAME = "rule_uuid"; | |||
public static final String RULE_UUID_COL_NAME = "rule_uuid"; | |||
private static final String STATUS_COL_NAME = "status"; | |||
private static final String TASK_UUID_COL_NAME = "task_uuid"; | |||
private static final String TEMPLATE_UUID_COL_NAME = "template_uuid"; | |||
@@ -1463,7 +1463,6 @@ public class CreateInitialSchema extends DdlChange { | |||
} | |||
private CreateTableBuilder newTableBuilder(String tableName) { | |||
return new CreateTableBuilder(getDialect(), tableName); | |||
} |
@@ -19,7 +19,6 @@ | |||
*/ | |||
package org.sonar.server.platform.db.migration.version.v95; | |||
import com.google.common.annotations.VisibleForTesting; | |||
import java.sql.Connection; | |||
import java.sql.SQLException; | |||
import org.sonar.db.Database; | |||
@@ -30,8 +29,7 @@ import org.sonar.server.platform.db.migration.step.DdlChange; | |||
import static org.sonar.server.platform.db.migration.version.v95.CreateRuleDescSectionsTable.RULE_DESCRIPTION_SECTIONS_TABLE; | |||
public class CreateIndexForRuleDescSections extends DdlChange { | |||
@VisibleForTesting | |||
static final String INDEX_NAME = "uniq_rule_desc_sections_kee"; | |||
public static final String INDEX_NAME = "uniq_rule_desc_sections_kee"; | |||
public CreateIndexForRuleDescSections(Database db) { | |||
super(db); |
@@ -31,7 +31,7 @@ import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVar | |||
public class CreateRuleDescSectionsTable extends CreateTableChange { | |||
static final String RULE_DESCRIPTION_SECTIONS_TABLE = "rule_desc_sections"; | |||
public static final String RULE_DESCRIPTION_SECTIONS_TABLE = "rule_desc_sections"; | |||
public CreateRuleDescSectionsTable(Database db) { |
@@ -0,0 +1,69 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2022 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.version.v96; | |||
import java.sql.Connection; | |||
import java.sql.SQLException; | |||
import org.sonar.db.Database; | |||
import org.sonar.db.DatabaseUtils; | |||
import org.sonar.server.platform.db.migration.def.ColumnDef; | |||
import org.sonar.server.platform.db.migration.def.VarcharColumnDef; | |||
import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder; | |||
import org.sonar.server.platform.db.migration.step.DdlChange; | |||
import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder; | |||
import static org.sonar.server.platform.db.migration.version.v95.CreateRuleDescSectionsTable.RULE_DESCRIPTION_SECTIONS_TABLE; | |||
public class AddContextColumnsToRuleDescSectionsTable extends DdlChange { | |||
static final String COLUMN_CONTEXT_KEY = "context_key"; | |||
static final String COLUMN_CONTEXT_DISPLAY_NAME = "context_display_name"; | |||
public AddContextColumnsToRuleDescSectionsTable(Database db) { | |||
super(db); | |||
} | |||
@Override | |||
public void execute(Context context) throws SQLException { | |||
try (Connection connection = getDatabase().getDataSource().getConnection()) { | |||
createContextKeyColumn(context, connection); | |||
createContextDisplayNameColumn(context, connection); | |||
} | |||
} | |||
private void createContextKeyColumn(Context context, Connection connection) { | |||
VarcharColumnDef contextKeyColumn = newVarcharColumnDefBuilder().setColumnName(COLUMN_CONTEXT_KEY).setIsNullable(true).setLimit(50).build(); | |||
createColumnIfNotExists(context, connection, contextKeyColumn); | |||
} | |||
private void createContextDisplayNameColumn(Context context, Connection connection) { | |||
VarcharColumnDef contextDisplayNameColumn = newVarcharColumnDefBuilder().setColumnName(COLUMN_CONTEXT_DISPLAY_NAME).setIsNullable(true).setLimit(50).build(); | |||
createColumnIfNotExists(context, connection, contextDisplayNameColumn); | |||
} | |||
private void createColumnIfNotExists(Context context, Connection connection, ColumnDef columnDef) { | |||
if (!DatabaseUtils.tableColumnExists(connection, RULE_DESCRIPTION_SECTIONS_TABLE, columnDef.getName())) { | |||
context.execute(new AddColumnsBuilder(getDialect(), RULE_DESCRIPTION_SECTIONS_TABLE) | |||
.addColumn(columnDef) | |||
.build()); | |||
} | |||
} | |||
} |
@@ -0,0 +1,62 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2022 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.version.v96; | |||
import java.sql.Connection; | |||
import java.sql.SQLException; | |||
import org.sonar.db.Database; | |||
import org.sonar.db.DatabaseUtils; | |||
import org.sonar.server.platform.db.migration.sql.CreateIndexBuilder; | |||
import org.sonar.server.platform.db.migration.step.DdlChange; | |||
import static org.sonar.server.platform.db.migration.version.v00.CreateInitialSchema.RULE_UUID_COL_NAME; | |||
import static org.sonar.server.platform.db.migration.version.v95.CreateRuleDescSectionsTable.RULE_DESCRIPTION_SECTIONS_TABLE; | |||
import static org.sonar.server.platform.db.migration.version.v96.AddContextColumnsToRuleDescSectionsTable.COLUMN_CONTEXT_KEY; | |||
public class CreateIndexForRuleDescSections extends DdlChange { | |||
static final String INDEX_NAME = "uniq_rule_desc_sections"; | |||
static final String COLUMN_KEE = "kee"; | |||
public CreateIndexForRuleDescSections(Database db) { | |||
super(db); | |||
} | |||
@Override | |||
public void execute(Context context) throws SQLException { | |||
try (Connection connection = getDatabase().getDataSource().getConnection()) { | |||
createRuleDescSectionUniqueIndex(context, connection); | |||
} | |||
} | |||
private static void createRuleDescSectionUniqueIndex(Context context, Connection connection) { | |||
if (!DatabaseUtils.indexExistsIgnoreCase(RULE_DESCRIPTION_SECTIONS_TABLE, INDEX_NAME, connection)) { | |||
context.execute(new CreateIndexBuilder() | |||
.setTable(RULE_DESCRIPTION_SECTIONS_TABLE) | |||
.setName(INDEX_NAME) | |||
.addColumn(RULE_UUID_COL_NAME) | |||
.addColumn(COLUMN_KEE) | |||
.addColumn(COLUMN_CONTEXT_KEY) | |||
.setUnique(true) | |||
.build()); | |||
} | |||
} | |||
} |
@@ -28,6 +28,9 @@ public class DbVersion96 implements DbVersion { | |||
public void addSteps(MigrationStepRegistry registry) { | |||
registry | |||
.add(6500, "remove root column from users table", DropRootColumnFromUsersTable.class) | |||
.add(6501, "Add columns 'context_key' and 'context_display_name' into rule_desc_sections", AddContextColumnsToRuleDescSectionsTable.class) | |||
.add(6502, "Drop unique index uniq_rule_desc_sections_kee", DropIndexForRuleDescSection.class) | |||
.add(6503, "Create unique uniq_rule_desc_sections", CreateIndexForRuleDescSections.class) | |||
; | |||
} | |||
} |
@@ -0,0 +1,34 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2022 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.version.v96; | |||
import org.sonar.db.Database; | |||
import org.sonar.server.platform.db.migration.step.DropIndexChange; | |||
import static org.sonar.server.platform.db.migration.version.v95.CreateIndexForRuleDescSections.INDEX_NAME; | |||
import static org.sonar.server.platform.db.migration.version.v95.CreateRuleDescSectionsTable.RULE_DESCRIPTION_SECTIONS_TABLE; | |||
public class DropIndexForRuleDescSection extends DropIndexChange { | |||
public DropIndexForRuleDescSection(Database db) { | |||
super(db, INDEX_NAME, RULE_DESCRIPTION_SECTIONS_TABLE); | |||
} | |||
} |
@@ -0,0 +1,68 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2022 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.version.v96; | |||
import java.sql.SQLException; | |||
import java.sql.Types; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.sonar.db.CoreDbTester; | |||
import static org.sonar.db.CoreDbTester.createForSchema; | |||
import static org.sonar.server.platform.db.migration.version.v95.CreateRuleDescSectionsTable.RULE_DESCRIPTION_SECTIONS_TABLE; | |||
import static org.sonar.server.platform.db.migration.version.v96.AddContextColumnsToRuleDescSectionsTable.COLUMN_CONTEXT_DISPLAY_NAME; | |||
import static org.sonar.server.platform.db.migration.version.v96.AddContextColumnsToRuleDescSectionsTable.COLUMN_CONTEXT_KEY; | |||
public class AddContextColumnsToRuleDescSectionsTableTest { | |||
@Rule | |||
public final CoreDbTester db = createForSchema(AddContextColumnsToRuleDescSectionsTableTest.class, "schema.sql"); | |||
private final AddContextColumnsToRuleDescSectionsTable addContextColumnsToRuleDescSectionsTable = new AddContextColumnsToRuleDescSectionsTable(db.database()); | |||
@Test | |||
public void column_context_key_should_be_added() throws SQLException { | |||
db.assertColumnDoesNotExist(RULE_DESCRIPTION_SECTIONS_TABLE, COLUMN_CONTEXT_KEY); | |||
addContextColumnsToRuleDescSectionsTable.execute(); | |||
db.assertColumnDefinition(RULE_DESCRIPTION_SECTIONS_TABLE, COLUMN_CONTEXT_KEY, Types.VARCHAR, 50, true); | |||
} | |||
@Test | |||
public void column_context_display_name_should_be_added() throws SQLException { | |||
db.assertColumnDoesNotExist(RULE_DESCRIPTION_SECTIONS_TABLE, COLUMN_CONTEXT_DISPLAY_NAME); | |||
addContextColumnsToRuleDescSectionsTable.execute(); | |||
db.assertColumnDefinition(RULE_DESCRIPTION_SECTIONS_TABLE, COLUMN_CONTEXT_DISPLAY_NAME, Types.VARCHAR, 50, true); | |||
} | |||
@Test | |||
public void migration_should_be_reentrant() throws SQLException { | |||
addContextColumnsToRuleDescSectionsTable.execute(); | |||
addContextColumnsToRuleDescSectionsTable.execute(); | |||
db.assertColumnDefinition(RULE_DESCRIPTION_SECTIONS_TABLE, COLUMN_CONTEXT_DISPLAY_NAME, Types.VARCHAR, 50, true); | |||
db.assertColumnDefinition(RULE_DESCRIPTION_SECTIONS_TABLE, COLUMN_CONTEXT_KEY, Types.VARCHAR, 50, true); | |||
} | |||
} |
@@ -0,0 +1,58 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2022 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.version.v96; | |||
import java.sql.SQLException; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.sonar.db.CoreDbTester; | |||
import static org.sonar.server.platform.db.migration.version.v00.CreateInitialSchema.RULE_UUID_COL_NAME; | |||
import static org.sonar.server.platform.db.migration.version.v95.CreateRuleDescSectionsTable.RULE_DESCRIPTION_SECTIONS_TABLE; | |||
import static org.sonar.server.platform.db.migration.version.v96.AddContextColumnsToRuleDescSectionsTable.COLUMN_CONTEXT_KEY; | |||
import static org.sonar.server.platform.db.migration.version.v96.CreateIndexForRuleDescSections.COLUMN_KEE; | |||
import static org.sonar.server.platform.db.migration.version.v96.CreateIndexForRuleDescSections.INDEX_NAME; | |||
public class CreateIndexForRuleDescSectionsTest { | |||
@Rule | |||
public final CoreDbTester db = CoreDbTester.createForSchema(CreateIndexForRuleDescSectionsTest.class, "schema.sql"); | |||
private final CreateIndexForRuleDescSections createIndexForRuleDescSections = new CreateIndexForRuleDescSections(db.database()); | |||
@Test | |||
public void migration_should_create_index() throws SQLException { | |||
db.assertIndexDoesNotExist(RULE_DESCRIPTION_SECTIONS_TABLE, INDEX_NAME); | |||
createIndexForRuleDescSections.execute(); | |||
db.assertUniqueIndex(RULE_DESCRIPTION_SECTIONS_TABLE, INDEX_NAME, RULE_UUID_COL_NAME, COLUMN_KEE, COLUMN_CONTEXT_KEY); | |||
} | |||
@Test | |||
public void migration_should_be_reentrant() throws SQLException { | |||
createIndexForRuleDescSections.execute(); | |||
createIndexForRuleDescSections.execute(); | |||
db.assertUniqueIndex(RULE_DESCRIPTION_SECTIONS_TABLE, INDEX_NAME, RULE_UUID_COL_NAME, COLUMN_KEE, COLUMN_CONTEXT_KEY); | |||
} | |||
} |
@@ -0,0 +1,55 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2022 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.version.v96; | |||
import java.sql.SQLException; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.sonar.db.CoreDbTester; | |||
import static org.sonar.db.CoreDbTester.createForSchema; | |||
import static org.sonar.server.platform.db.migration.version.v95.CreateIndexForRuleDescSections.INDEX_NAME; | |||
import static org.sonar.server.platform.db.migration.version.v95.CreateRuleDescSectionsTable.RULE_DESCRIPTION_SECTIONS_TABLE; | |||
public class DropIndexForRuleDescSectionTest { | |||
@Rule | |||
public final CoreDbTester db = createForSchema(DropIndexForRuleDescSectionTest.class, "schema.sql"); | |||
private final DropIndexForRuleDescSection dropIndexForRuleDescSection = new DropIndexForRuleDescSection(db.database()); | |||
@Test | |||
public void migration_should_drop_unique_index() throws SQLException { | |||
db.assertUniqueIndex(RULE_DESCRIPTION_SECTIONS_TABLE, INDEX_NAME, "rule_uuid", "kee"); | |||
dropIndexForRuleDescSection.execute(); | |||
db.assertIndexDoesNotExist(RULE_DESCRIPTION_SECTIONS_TABLE, INDEX_NAME); | |||
} | |||
@Test | |||
public void migration_should_be_reentrant() throws SQLException { | |||
dropIndexForRuleDescSection.execute(); | |||
dropIndexForRuleDescSection.execute(); | |||
db.assertIndexDoesNotExist(RULE_DESCRIPTION_SECTIONS_TABLE, INDEX_NAME); | |||
} | |||
} |
@@ -0,0 +1,7 @@ | |||
CREATE TABLE "RULE_DESC_SECTIONS"( | |||
"UUID" CHARACTER VARYING(40) NOT NULL, | |||
"RULE_UUID" CHARACTER VARYING(40) NOT NULL, | |||
"KEE" CHARACTER VARYING(50) NOT NULL, | |||
"CONTENT" CHARACTER LARGE OBJECT NOT NULL | |||
); | |||
ALTER TABLE "RULE_DESC_SECTIONS" ADD CONSTRAINT "PK_RULE_DESC_SECTIONS" PRIMARY KEY("UUID"); |
@@ -0,0 +1,9 @@ | |||
CREATE TABLE "RULE_DESC_SECTIONS"( | |||
"UUID" CHARACTER VARYING(40) NOT NULL, | |||
"RULE_UUID" CHARACTER VARYING(40) NOT NULL, | |||
"KEE" CHARACTER VARYING(50) NOT NULL, | |||
"CONTENT" CHARACTER LARGE OBJECT NOT NULL, | |||
"CONTEXT_KEY" CHARACTER VARYING(40), | |||
"CONTEXT_DISPLAY_NAME" CHARACTER VARYING(50) | |||
); | |||
ALTER TABLE "RULE_DESC_SECTIONS" ADD CONSTRAINT "PK_RULE_DESC_SECTIONS" PRIMARY KEY("UUID"); |
@@ -0,0 +1,10 @@ | |||
CREATE TABLE "RULE_DESC_SECTIONS"( | |||
"UUID" CHARACTER VARYING(40) NOT NULL, | |||
"RULE_UUID" CHARACTER VARYING(40) NOT NULL, | |||
"KEE" CHARACTER VARYING(50) NOT NULL, | |||
"CONTENT" CHARACTER LARGE OBJECT NOT NULL, | |||
"CONTEXT_KEY" CHARACTER VARYING(40), | |||
"CONTEXT_DISPLAY_NAME" CHARACTER VARYING(50) | |||
); | |||
ALTER TABLE "RULE_DESC_SECTIONS" ADD CONSTRAINT "PK_RULE_DESC_SECTIONS" PRIMARY KEY("UUID"); | |||
CREATE UNIQUE INDEX "UNIQ_RULE_DESC_SECTIONS_KEE" ON "RULE_DESC_SECTIONS"("RULE_UUID" NULLS FIRST, "KEE" NULLS FIRST); |