import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.sonar.api.utils.System2;
+import org.sonar.core.util.UuidFactory;
import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.Dao;
import org.sonar.db.DatabaseUtils;
public class QualityProfileDao implements Dao {
private final System2 system;
+ private final UuidFactory uuidFactory;
- public QualityProfileDao(System2 system) {
+ public QualityProfileDao(UuidFactory uuidFactory, System2 system) {
+ this.uuidFactory = uuidFactory;
this.system = system;
}
}
public void insertProjectProfileAssociation(DbSession dbSession, ProjectDto project, QProfileDto profile) {
- mapper(dbSession).insertProjectProfileAssociation(project.getUuid(), profile.getKee());
+ mapper(dbSession).insertProjectProfileAssociation(uuidFactory.create(), project.getUuid(), profile.getKee());
}
public void deleteProjectProfileAssociation(DbSession dbSession, ProjectDto project, QProfileDto profile) {
@Param("languages") Collection<String> languages);
void insertProjectProfileAssociation(
+ @Param("uuid") String uuid,
@Param("projectUuid") String projectUuid,
@Param("profileUuid") String profileUuid);
<insert id="insertProjectProfileAssociation" useGeneratedKeys="false">
insert into project_qprofiles (
+ uuid,
project_uuid,
profile_key
) values (
+ #{uuid, jdbcType=VARCHAR},
#{projectUuid, jdbcType=VARCHAR},
#{profileUuid, jdbcType=VARCHAR}
)
<select id="selectSelectedProjects" resultType="org.sonar.db.qualityprofile.ProjectQprofileAssociationDto">
select
- pp.id as id,
pj.uuid as projectUuid,
pj.kee as projectKey,
pj.name as projectName,
</select>
<select id="selectDeselectedProjects" resultType="org.sonar.db.qualityprofile.ProjectQprofileAssociationDto">
- SELECT pp.id as id, pj.uuid as projectUuid, pj.kee as projectKey, pj.name as projectName, pp.profile_key as profileKey
+ SELECT pj.uuid as projectUuid, pj.kee as projectKey, pj.name as projectName, pp.profile_key as profileKey
FROM components pj
LEFT JOIN project_qprofiles pp ON pp.project_uuid = pj.uuid
AND pp.profile_key = #{profileUuid, jdbcType=VARCHAR}
</select>
<select id="selectProjectAssociations" resultType="org.sonar.db.qualityprofile.ProjectQprofileAssociationDto">
- SELECT pp.id as id, pj.uuid as projectUuid, pj.kee as projectKey, pj.name as projectName, pp.profile_key as profileKey
+ SELECT pj.uuid as projectUuid, pj.kee as projectKey, pj.name as projectName, pp.profile_key as profileKey
FROM components pj
LEFT JOIN project_qprofiles pp ON pp.project_uuid = pj.uuid
AND pp.profile_key = #{profileUuid, jdbcType=VARCHAR}
CREATE UNIQUE INDEX "UNIQ_PROJECT_QGATES" ON "PROJECT_QGATES"("PROJECT_UUID", "QUALITY_GATE_UUID");
CREATE TABLE "PROJECT_QPROFILES"(
- "ID" INTEGER NOT NULL AUTO_INCREMENT (1,1),
"PROJECT_UUID" VARCHAR(50) NOT NULL,
- "PROFILE_KEY" VARCHAR(50) NOT NULL
+ "PROFILE_KEY" VARCHAR(50) NOT NULL,
+ "UUID" VARCHAR(40) NOT NULL
);
-ALTER TABLE "PROJECT_QPROFILES" ADD CONSTRAINT "PK_PROJECT_QPROFILES" PRIMARY KEY("ID");
+ALTER TABLE "PROJECT_QPROFILES" ADD CONSTRAINT "PK_PROJECT_QPROFILES" PRIMARY KEY("UUID");
CREATE UNIQUE INDEX "UNIQ_PROJECT_QPROFILES" ON "PROJECT_QPROFILES"("PROJECT_UUID", "PROFILE_KEY");
CREATE TABLE "PROJECTS"(
import org.sonar.server.platform.db.migration.version.v83.projectmeasures.DropPrimaryKeyOnIdColumnOfProjectMeasuresTable;
import org.sonar.server.platform.db.migration.version.v83.projectmeasures.MakeProjectMeasuresUuidColumnNotNullable;
import org.sonar.server.platform.db.migration.version.v83.projectmeasures.PopulateProjectMeasureUuid;
+import org.sonar.server.platform.db.migration.version.v83.projectqprofiles.AddPrimaryKeyOnUuidColumnOfProjectQProfilesTable;
+import org.sonar.server.platform.db.migration.version.v83.projectqprofiles.AddUuidColumnToProjectQProfilesTable;
+import org.sonar.server.platform.db.migration.version.v83.projectqprofiles.DropIdColumnOfProjectQProfilesTable;
+import org.sonar.server.platform.db.migration.version.v83.projectqprofiles.DropPrimaryKeyOnIdColumnOfProjectQProfilesTable;
+import org.sonar.server.platform.db.migration.version.v83.projectqprofiles.MakeProjectQProfilesUuidColumnNotNullable;
+import org.sonar.server.platform.db.migration.version.v83.projectqprofiles.PopulateProjectQProfilesUuid;
import org.sonar.server.platform.db.migration.version.v83.snapshots.issues.AddPrimaryKeyOnUuidColumnOfSnapshotsTable;
import org.sonar.server.platform.db.migration.version.v83.snapshots.issues.DropIdColumnOfSnapshotsTable;
import org.sonar.server.platform.db.migration.version.v83.snapshots.issues.DropPrimaryKeyOnIdColumnOfSnapshotsTable;
.add(3444, "Add primary key on 'UUID' column of 'USER_TOKENS' table", AddPrimaryKeyOnUuidColumnOfUserTokensTable.class)
.add(3445, "Drop column 'ID' of 'USER_TOKENS' table", DropIdColumnOfUserTokensTable.class)
-
-
-
-
-
+ // Migration on PROJECT_QPROFILES table
+ .add(3446, "Add 'uuid' column for 'PROJECT_QPROFILES'", AddUuidColumnToProjectQProfilesTable.class)
+ .add(3447, "Populate 'uuid' column for 'PROJECT_QPROFILES'", PopulateProjectQProfilesUuid.class)
+ .add(3448, "Make 'uuid' column not nullable for 'PROJECT_QPROFILES'", MakeProjectQProfilesUuidColumnNotNullable.class)
+ .add(3449, "Drop primary key on 'ID' column of 'PROJECT_QPROFILES' table", DropPrimaryKeyOnIdColumnOfProjectQProfilesTable.class)
+ .add(3450, "Add primary key on 'UUID' column of 'PROJECT_QPROFILES' table", AddPrimaryKeyOnUuidColumnOfProjectQProfilesTable.class)
+ .add(3451, "Drop column 'ID' of 'PROJECT_QPROFILES' table", DropIdColumnOfProjectQProfilesTable.class)
;
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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.v83.projectqprofiles;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+import org.sonar.server.platform.db.migration.version.v83.util.AddPrimaryKeyBuilder;
+
+public class AddPrimaryKeyOnUuidColumnOfProjectQProfilesTable extends DdlChange {
+
+ public AddPrimaryKeyOnUuidColumnOfProjectQProfilesTable(Database db) {
+ super(db);
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ context.execute(new AddPrimaryKeyBuilder("project_qprofiles", "uuid").build());
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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.v83.projectqprofiles;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+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;
+
+public class AddUuidColumnToProjectQProfilesTable extends DdlChange {
+ private static final String TABLE = "project_qprofiles";
+
+ private static final VarcharColumnDef uuidColumnDefinition = newVarcharColumnDefBuilder()
+ .setColumnName("uuid")
+ .setIsNullable(true)
+ .setDefaultValue(null)
+ .setLimit(VarcharColumnDef.UUID_SIZE)
+ .build();
+
+ public AddUuidColumnToProjectQProfilesTable(Database db) {
+ super(db);
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ context.execute(new AddColumnsBuilder(getDialect(), TABLE)
+ .addColumn(uuidColumnDefinition)
+ .build());
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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.v83.projectqprofiles;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.sql.DropColumnsBuilder;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+public class DropIdColumnOfProjectQProfilesTable extends DdlChange {
+
+ private Database db;
+
+ public DropIdColumnOfProjectQProfilesTable(Database db) {
+ super(db);
+ this.db = db;
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ context.execute(new DropColumnsBuilder(db.getDialect(), "project_qprofiles", "id").build());
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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.v83.projectqprofiles;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+import org.sonar.server.platform.db.migration.version.v83.util.DropPrimaryKeySqlGenerator;
+
+public class DropPrimaryKeyOnIdColumnOfProjectQProfilesTable extends DdlChange {
+
+ private final DropPrimaryKeySqlGenerator dropPrimaryKeySqlGenerator;
+
+ public DropPrimaryKeyOnIdColumnOfProjectQProfilesTable(Database db, DropPrimaryKeySqlGenerator dropPrimaryKeySqlGenerator) {
+ super(db);
+ this.dropPrimaryKeySqlGenerator = dropPrimaryKeySqlGenerator;
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ context.execute(dropPrimaryKeySqlGenerator.generate("project_qprofiles", "id"));
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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.v83.projectqprofiles;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.sql.AlterColumnsBuilder;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
+
+public class MakeProjectQProfilesUuidColumnNotNullable extends DdlChange {
+ private static final String TABLE = "project_qprofiles";
+
+ private static final VarcharColumnDef uuidColumnDefinition = newVarcharColumnDefBuilder()
+ .setColumnName("uuid")
+ .setIsNullable(false)
+ .setDefaultValue(null)
+ .setLimit(VarcharColumnDef.UUID_SIZE)
+ .build();
+
+ public MakeProjectQProfilesUuidColumnNotNullable(Database db) {
+ super(db);
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ context.execute(new AlterColumnsBuilder(getDialect(), TABLE)
+ .updateColumn(uuidColumnDefinition)
+ .build());
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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.v83.projectqprofiles;
+
+import java.sql.SQLException;
+import java.util.concurrent.atomic.AtomicLong;
+import org.sonar.core.util.UuidFactory;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.step.DataChange;
+import org.sonar.server.platform.db.migration.step.MassUpdate;
+
+public class PopulateProjectQProfilesUuid extends DataChange {
+
+ private final UuidFactory uuidFactory;
+
+ public PopulateProjectQProfilesUuid(Database db, UuidFactory uuidFactory) {
+ super(db);
+ this.uuidFactory = uuidFactory;
+ }
+
+ @Override
+ protected void execute(Context context) throws SQLException {
+ MassUpdate massUpdate = context.prepareMassUpdate();
+
+ massUpdate.select("select id from project_qprofiles where uuid is null");
+ massUpdate.update("update project_qprofiles set uuid = ? where id = ?");
+
+ massUpdate.execute((row, update) -> {
+ update.setString(1, uuidFactory.create());
+ update.setLong(2, row.getLong(1));
+ return true;
+ });
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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.v83.projectqprofiles;
+
+import java.sql.SQLException;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.db.CoreDbTester;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+public class AddPrimaryKeyOnUuidColumnOfProjectQProfilesTableTest {
+ @Rule
+ public CoreDbTester db = CoreDbTester.createForSchema(AddPrimaryKeyOnUuidColumnOfProjectQProfilesTableTest.class, "schema.sql");
+
+ private DdlChange underTest = new AddPrimaryKeyOnUuidColumnOfProjectQProfilesTable(db.database());
+
+ @Test
+ public void execute() throws SQLException {
+ underTest.execute();
+
+ db.assertPrimaryKey("project_qprofiles", "pk_project_qprofiles", "uuid");
+ }
+
+ @Test
+ public void migration_is_not_re_entrant() throws SQLException {
+ underTest.execute();
+
+ assertThatThrownBy(() -> underTest.execute()).isInstanceOf(IllegalStateException.class);
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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.v83.projectqprofiles;
+
+import java.sql.SQLException;
+import java.sql.Types;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.core.util.UuidFactory;
+import org.sonar.core.util.UuidFactoryFast;
+import org.sonar.db.CoreDbTester;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class AddUuidColumnToProjectQProfilesTableTest {
+
+ @Rule
+ public CoreDbTester db = CoreDbTester.createForSchema(AddUuidColumnToProjectQProfilesTableTest.class, "schema.sql");
+
+ private UuidFactory uuidFactory = UuidFactoryFast.getInstance();
+
+ private DdlChange underTest = new AddUuidColumnToProjectQProfilesTable(db.database());
+
+ @Before
+ public void setup() {
+ insertProjectQProfile(1L);
+ insertProjectQProfile(2L);
+ insertProjectQProfile(3L);
+ }
+
+ @Test
+ public void add_uuid_column_to_project_qprofiles() throws SQLException {
+ underTest.execute();
+
+ db.assertColumnDefinition("project_qprofiles", "uuid", Types.VARCHAR, 40, true);
+
+ assertThat(db.countSql("select count(id) from project_qprofiles"))
+ .isEqualTo(3);
+ }
+
+ private void insertProjectQProfile(Long id) {
+ db.executeInsert("project_qprofiles",
+ "id", id,
+ "project_uuid", uuidFactory.create(),
+ "profile_key", uuidFactory.create());
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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.v83.projectqprofiles;
+
+import java.sql.SQLException;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.db.CoreDbTester;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+public class DropIdColumnOfProjectQProfilesTableTest {
+ @Rule
+ public CoreDbTester db = CoreDbTester.createForSchema(DropIdColumnOfProjectQProfilesTableTest.class, "schema.sql");
+
+ private DdlChange underTest = new DropIdColumnOfProjectQProfilesTable(db.database());
+
+ @Test
+ public void execute() throws SQLException {
+ underTest.execute();
+
+ db.assertColumnDoesNotExist("project_qprofiles", "id");
+ }
+
+ @Test
+ public void migration_is_not_re_entrant() throws SQLException {
+ underTest.execute();
+
+ assertThatThrownBy(() -> underTest.execute()).isInstanceOf(IllegalStateException.class);
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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.v83.projectqprofiles;
+
+import java.sql.SQLException;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.db.CoreDbTester;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+import org.sonar.server.platform.db.migration.version.v83.util.DropPrimaryKeySqlGenerator;
+import org.sonar.server.platform.db.migration.version.v83.util.SqlHelper;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+public class DropPrimaryKeyOnIdColumnOfProjectQProfilesTableTest {
+ private static final String TABLE_NAME = "project_qprofiles";
+ @Rule
+ public CoreDbTester db = CoreDbTester.createForSchema(DropPrimaryKeyOnIdColumnOfProjectQProfilesTableTest.class, "schema.sql");
+
+ private DropPrimaryKeySqlGenerator dropPrimaryKeySqlGenerator = new DropPrimaryKeySqlGenerator(db.database(), new SqlHelper(db.database()));
+
+ private DdlChange underTest = new DropPrimaryKeyOnIdColumnOfProjectQProfilesTable(db.database(), dropPrimaryKeySqlGenerator);
+
+ @Test
+ public void execute() throws SQLException {
+ underTest.execute();
+
+ db.assertNoPrimaryKey(TABLE_NAME);
+ }
+
+ @Test
+ public void migration_is_not_re_entrant() throws SQLException {
+ underTest.execute();
+
+ assertThatThrownBy(() -> underTest.execute()).isInstanceOf(IllegalStateException.class);
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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.v83.projectqprofiles;
+
+import java.sql.SQLException;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.db.CoreDbTester;
+import org.sonar.server.platform.db.migration.step.MigrationStep;
+
+import static java.sql.Types.VARCHAR;
+
+public class MakeProjectQProfilesUuidColumnNotNullableTest {
+
+ @Rule
+ public CoreDbTester db = CoreDbTester.createForSchema(MakeProjectQProfilesUuidColumnNotNullableTest.class, "schema.sql");
+
+ private MigrationStep underTest = new MakeProjectQProfilesUuidColumnNotNullable(db.database());
+
+ @Test
+ public void uuid_column_is_not_null() throws SQLException {
+ underTest.execute();
+
+ db.assertColumnDefinition("project_qprofiles", "uuid", VARCHAR, null, false);
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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.v83.projectqprofiles;
+
+import java.sql.SQLException;
+import java.util.Objects;
+import java.util.stream.Collectors;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.core.util.UuidFactory;
+import org.sonar.core.util.UuidFactoryFast;
+import org.sonar.db.CoreDbTester;
+import org.sonar.server.platform.db.migration.step.DataChange;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class PopulateProjectQProfilesUuidTest {
+
+ @Rule
+ public CoreDbTester db = CoreDbTester.createForSchema(PopulateProjectQProfilesUuidTest.class, "schema.sql");
+
+ private UuidFactory uuidFactory = UuidFactoryFast.getInstance();
+ private DataChange underTest = new PopulateProjectQProfilesUuid(db.database(), uuidFactory);
+
+ @Test
+ public void populate_uuids() throws SQLException {
+ insertProjectQProfile(1L);
+ insertProjectQProfile(2L);
+ insertProjectQProfile(3L);
+
+ underTest.execute();
+
+ verifyUuidsAreNotNull();
+ }
+
+ @Test
+ public void migration_is_reentrant() throws SQLException {
+ insertProjectQProfile(1L);
+ insertProjectQProfile(2L);
+ insertProjectQProfile(3L);
+
+ underTest.execute();
+ // re-entrant
+ underTest.execute();
+
+ verifyUuidsAreNotNull();
+ }
+
+ private void verifyUuidsAreNotNull() {
+ assertThat(db.select("select uuid from project_qprofiles")
+ .stream()
+ .map(row -> row.get("UUID"))
+ .filter(Objects::isNull)
+ .collect(Collectors.toList())).isEmpty();
+ }
+
+ private void insertProjectQProfile(Long id) {
+ db.executeInsert("project_qprofiles",
+ "id", id,
+ "project_uuid", uuidFactory.create(),
+ "profile_key", uuidFactory.create());
+ }
+}
--- /dev/null
+CREATE TABLE "PROJECT_QPROFILES"(
+ "ID" INTEGER NOT NULL AUTO_INCREMENT (1,1),
+ "UUID" VARCHAR(40) NOT NULL,
+ "PROJECT_UUID" VARCHAR(50) NOT NULL,
+ "PROFILE_KEY" VARCHAR(50) NOT NULL
+);
+CREATE UNIQUE INDEX "UNIQ_PROJECT_QPROFILES" ON "PROJECT_QPROFILES"("PROJECT_UUID", "PROFILE_KEY");
--- /dev/null
+CREATE TABLE "PROJECT_QPROFILES"(
+ "ID" INTEGER NOT NULL AUTO_INCREMENT (1,1),
+ "PROJECT_UUID" VARCHAR(50) NOT NULL,
+ "PROFILE_KEY" VARCHAR(50) NOT NULL
+);
+ALTER TABLE "PROJECT_QPROFILES" ADD CONSTRAINT "PK_PROJECT_QPROFILES" PRIMARY KEY("ID");
+CREATE UNIQUE INDEX "UNIQ_PROJECT_QPROFILES" ON "PROJECT_QPROFILES"("PROJECT_UUID", "PROFILE_KEY");
--- /dev/null
+CREATE TABLE "PROJECT_QPROFILES"(
+ "ID" INTEGER NOT NULL AUTO_INCREMENT (1,1),
+ "UUID" VARCHAR(40) NOT NULL,
+ "PROJECT_UUID" VARCHAR(50) NOT NULL,
+ "PROFILE_KEY" VARCHAR(50) NOT NULL
+);
+ALTER TABLE "PROJECT_QPROFILES" ADD CONSTRAINT "PK_PROJECT_QPROFILES" PRIMARY KEY("UUID");
+CREATE UNIQUE INDEX "UNIQ_PROJECT_QPROFILES" ON "PROJECT_QPROFILES"("PROJECT_UUID", "PROFILE_KEY");
--- /dev/null
+CREATE TABLE "PROJECT_QPROFILES"(
+ "ID" INTEGER NOT NULL AUTO_INCREMENT (1,1),
+ "UUID" VARCHAR(40) NOT NULL,
+ "PROJECT_UUID" VARCHAR(50) NOT NULL,
+ "PROFILE_KEY" VARCHAR(50) NOT NULL
+);
+ALTER TABLE "PROJECT_QPROFILES" ADD CONSTRAINT "PK_PROJECT_QPROFILES" PRIMARY KEY("ID");
+CREATE UNIQUE INDEX "UNIQ_PROJECT_QPROFILES" ON "PROJECT_QPROFILES"("PROJECT_UUID", "PROFILE_KEY");
--- /dev/null
+CREATE TABLE "PROJECT_QPROFILES"(
+ "ID" INTEGER NOT NULL AUTO_INCREMENT (1,1),
+ "UUID" VARCHAR(40),
+ "PROJECT_UUID" VARCHAR(50) NOT NULL,
+ "PROFILE_KEY" VARCHAR(50) NOT NULL
+);
+ALTER TABLE "PROJECT_QPROFILES" ADD CONSTRAINT "PK_PROJECT_QPROFILES" PRIMARY KEY("ID");
+CREATE UNIQUE INDEX "UNIQ_PROJECT_QPROFILES" ON "PROJECT_QPROFILES"("PROJECT_UUID", "PROFILE_KEY");
--- /dev/null
+CREATE TABLE "PROJECT_QPROFILES"(
+ "ID" INTEGER NOT NULL AUTO_INCREMENT (1,1),
+ "UUID" VARCHAR(40),
+ "PROJECT_UUID" VARCHAR(50) NOT NULL,
+ "PROFILE_KEY" VARCHAR(50) NOT NULL
+);
+ALTER TABLE "PROJECT_QPROFILES" ADD CONSTRAINT "PK_PROJECT_QPROFILES" PRIMARY KEY("ID");
+CREATE UNIQUE INDEX "UNIQ_PROJECT_QPROFILES" ON "PROJECT_QPROFILES"("PROJECT_UUID", "PROFILE_KEY");