Browse Source

SONAR-13193 Stop using legacy project ID and use project UUID instead

tags/8.3.0.34182
Duarte Meneses 4 years ago
parent
commit
32c274e7d7
28 changed files with 376 additions and 115 deletions
  1. 4
    17
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistComponentsStep.java
  2. 4
    5
      server/sonar-db-dao/src/schema/schema-sq.ddl
  3. 7
    1
      server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/MigrationConfigurationModule.java
  4. 3
    1
      server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/CreateTableBuilder.java
  5. 2
    16
      server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/AddComponentUuidColumnToGroupRoles.java
  6. 1
    11
      server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/AddComponentUuidColumnToProperties.java
  7. 3
    3
      server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/AddComponentUuidColumnToUserRoles.java
  8. 7
    5
      server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/DropIdFromComponentsTable.java
  9. 18
    1
      server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/DropResourceIdFromGroupRolesTable.java
  10. 7
    11
      server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/MigrateResourceIdToUuidInGroupRoles.java
  11. 6
    11
      server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/MigrateResourceIdToUuidInProperties.java
  12. 6
    10
      server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/MigrateResourceIdToUuidInUserRoles.java
  13. 87
    0
      server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/util/DropPrimaryKeySqlGenerator.java
  14. 104
    0
      server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/util/GetConstraintHelper.java
  15. 1
    7
      server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/MigrationConfigurationModuleTest.java
  16. 1
    2
      server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/AddComponentUuidColumnToGroupRolesTest.java
  17. 1
    1
      server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/AddComponentUuidColumnToPropertiesTest.java
  18. 1
    1
      server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/AddComponentUuidColumnToUserRolesTest.java
  19. 4
    4
      server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/DropIdFromComponentsTableTest.java
  20. 4
    4
      server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/DropResourceIdFromGroupRolesTableTest.java
  21. 3
    0
      server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/MigrateResourceIdToUuidInGroupRolesTest.java
  22. 2
    0
      server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/MigrateResourceIdToUuidInPropertiesTest.java
  23. 3
    0
      server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/MigrateResourceIdToUuidInUserRolesTest.java
  24. 96
    0
      server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/util/DropPrimaryKeySqlGeneratorTest.java
  25. 0
    1
      server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/DropResourceIdFromGroupRolesTableTest/schema.sql
  26. 0
    1
      server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/DropResourceIdFromPropertiesTableTest/schema.sql
  27. 0
    1
      server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/MigrateResourceIdToUuidInPropertiesTest/schema.sql
  28. 1
    1
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/ProjectStatusAction.java

+ 4
- 17
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistComponentsStep.java View File

@@ -19,7 +19,6 @@
*/
package org.sonar.ce.task.projectanalysis.step;

import com.google.common.base.Predicate;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
@@ -27,8 +26,8 @@ import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.resources.Qualifiers;
@@ -51,7 +50,6 @@ import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentUpdateDto;

import static com.google.common.collect.FluentIterable.from;
import static java.util.Optional.ofNullable;
import static org.sonar.ce.task.projectanalysis.component.ComponentVisitor.Order.PRE_ORDER;
import static org.sonar.db.component.ComponentDto.UUID_PATH_OF_ROOT;
@@ -166,7 +164,6 @@ public class PersistComponentsStep implements ComputationStep {
private final DbSession dbSession;
@Nullable
private final String mainBranchProjectUuid;
private int componentRef = 1;

PersistComponentStepsVisitor(Map<String, ComponentDto> existingComponentDtosByUuids, DbSession dbSession, @Nullable String mainBranchProjectUuid) {
super(
@@ -395,9 +392,9 @@ public class PersistComponentsStep implements ComputationStep {
private static void setParentModuleProperties(ComponentDto componentDto, PathAwareVisitor.Path<ComponentDtoHolder> path) {
componentDto.setProjectUuid(path.root().getDto().uuid());

ComponentDto parentModule = from(path.getCurrentPath())
.filter(ParentModulePathElement.INSTANCE)
.first()
ComponentDto parentModule = StreamSupport.stream(path.getCurrentPath().spliterator(), false)
.filter(p -> p.getComponent().getType() == Component.Type.PROJECT)
.findFirst()
.get()
.getElement().getDto();
componentDto.setUuidPath(formatUuidPathFromParent(path.parent().getDto()));
@@ -446,14 +443,4 @@ public class PersistComponentsStep implements ComputationStep {
this.dto = dto;
}
}

private enum ParentModulePathElement implements Predicate<PathAwareVisitor.PathElement<ComponentDtoHolder>> {
INSTANCE;

@Override
public boolean apply(@Nonnull PathAwareVisitor.PathElement<ComponentDtoHolder> input) {
return input.getComponent().getType() == Component.Type.PROJECT;
}
}

}

+ 4
- 5
server/sonar-db-dao/src/schema/schema-sq.ddl View File

@@ -320,11 +320,11 @@ CREATE TABLE "GROUP_ROLES"(
"ORGANIZATION_UUID" VARCHAR(40) NOT NULL,
"GROUP_ID" INTEGER,
"ROLE" VARCHAR(64) NOT NULL,
"COMPONENT_UUID" VARCHAR(50)
"COMPONENT_UUID" VARCHAR(40)
);
ALTER TABLE "GROUP_ROLES" ADD CONSTRAINT "PK_GROUP_ROLES" PRIMARY KEY("ID");
CREATE INDEX "GROUP_ROLES_COMPONENT_UUID" ON "GROUP_ROLES"("COMPONENT_UUID");
CREATE UNIQUE INDEX "GROUP_ROLES_UNIQ" ON "GROUP_ROLES"("ORGANIZATION_UUID", "GROUP_ID", "COMPONENT_UUID", "ROLE");
CREATE UNIQUE INDEX "UNIQ_GROUP_ROLES" ON "GROUP_ROLES"("ORGANIZATION_UUID", "GROUP_ID", "COMPONENT_UUID", "ROLE");

CREATE TABLE "GROUPS"(
"ID" INTEGER NOT NULL AUTO_INCREMENT (1,1),
@@ -737,11 +737,10 @@ CREATE TABLE "PROPERTIES"(
"TEXT_VALUE" VARCHAR(4000),
"CLOB_VALUE" CLOB(2147483647),
"CREATED_AT" BIGINT NOT NULL,
"COMPONENT_UUID" VARCHAR(50)
"COMPONENT_UUID" VARCHAR(40)
);
ALTER TABLE "PROPERTIES" ADD CONSTRAINT "PK_PROPERTIES" PRIMARY KEY("ID");
CREATE INDEX "PROPERTIES_KEY" ON "PROPERTIES"("PROP_KEY");
CREATE INDEX "PROPERTIES_COMPONENT_UUID" ON "PROPERTIES"("COMPONENT_UUID");

CREATE TABLE "QPROFILE_CHANGES"(
"KEE" VARCHAR(40) NOT NULL,
@@ -929,7 +928,7 @@ CREATE TABLE "USER_ROLES"(
"ORGANIZATION_UUID" VARCHAR(40) NOT NULL,
"USER_ID" INTEGER,
"ROLE" VARCHAR(64) NOT NULL,
"COMPONENT_UUID" VARCHAR(50)
"COMPONENT_UUID" VARCHAR(40)
);
ALTER TABLE "USER_ROLES" ADD CONSTRAINT "PK_USER_ROLES" PRIMARY KEY("ID");
CREATE INDEX "USER_ROLES_USER" ON "USER_ROLES"("USER_ID");

+ 7
- 1
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/MigrationConfigurationModule.java View File

@@ -29,6 +29,8 @@ import org.sonar.server.platform.db.migration.version.v80.DbVersion80;
import org.sonar.server.platform.db.migration.version.v81.DbVersion81;
import org.sonar.server.platform.db.migration.version.v82.DbVersion82;
import org.sonar.server.platform.db.migration.version.v83.DbVersion83;
import org.sonar.server.platform.db.migration.version.v83.util.DropPrimaryKeySqlGenerator;
import org.sonar.server.platform.db.migration.version.v83.util.GetConstraintHelper;

public class MigrationConfigurationModule extends Module {
@Override
@@ -47,6 +49,10 @@ public class MigrationConfigurationModule extends Module {

// history
MigrationHistoryImpl.class,
MigrationHistoryMeddler.class);
MigrationHistoryMeddler.class,

// Only needed for 8.3
GetConstraintHelper.class,
DropPrimaryKeySqlGenerator.class);
}
}

+ 3
- 1
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/CreateTableBuilder.java View File

@@ -53,6 +53,8 @@ import static org.sonar.server.platform.db.migration.def.Validations.validateTab

public class CreateTableBuilder {

public static final String PRIMARY_KEY_PREFIX = "pk_";

private final Dialect dialect;
private final String tableName;
private final List<ColumnDef> columnDefs = new ArrayList<>();
@@ -234,7 +236,7 @@ public class CreateTableBuilder {

private void appendPkConstraintName(StringBuilder res) {
if (pkConstraintName == null) {
res.append("pk_").append(tableName);
res.append(PRIMARY_KEY_PREFIX).append(tableName);
} else {
res.append(pkConstraintName.toLowerCase(Locale.ENGLISH));
}

+ 2
- 16
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/AddComponentUuidColumnToGroupRoles.java View File

@@ -26,14 +26,12 @@ import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
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.def.IntegerColumnDef.newIntegerColumnDefBuilder;
import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;

public class AddComponentUuidColumnToGroupRoles extends DdlChange {
public class AddComponentUuidColumnToGroupRoles extends DdlChange {
private static final String TABLE = "group_roles";
private static final String NEW_COLUMN = "component_uuid";
private static final String INDEX1 = "group_roles_component_uuid";
private static final String INDEX2 = "group_roles_uniq";

public AddComponentUuidColumnToGroupRoles(Database db) {
super(db);
@@ -43,7 +41,7 @@ public class AddComponentUuidColumnToGroupRoles extends DdlChange {
public void execute(Context context) throws SQLException {
VarcharColumnDef column = newVarcharColumnDefBuilder()
.setColumnName(NEW_COLUMN)
.setLimit(50)
.setLimit(VarcharColumnDef.UUID_SIZE)
.setIsNullable(true)
.build();
context.execute(new AddColumnsBuilder(getDialect(), TABLE)
@@ -56,17 +54,5 @@ public class AddComponentUuidColumnToGroupRoles extends DdlChange {
.setName(INDEX1)
.setUnique(false);
context.execute(index1.build());


CreateIndexBuilder index2 = new CreateIndexBuilder()
.setTable(TABLE)
.addColumn(newVarcharColumnDefBuilder().setColumnName("organization_uuid").setLimit(40).build())
.addColumn(newIntegerColumnDefBuilder().setColumnName("group_id").build())
.addColumn(column)
.addColumn(newVarcharColumnDefBuilder().setColumnName("role").setLimit(64).build())
.setName(INDEX2)
.setUnique(true);
context.execute(index2.build());

}
}

+ 1
- 11
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/AddComponentUuidColumnToProperties.java View File

@@ -23,7 +23,6 @@ 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.sql.CreateIndexBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;

import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
@@ -31,7 +30,6 @@ import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVar
public class AddComponentUuidColumnToProperties extends DdlChange {
private static final String TABLE = "properties";
private static final String NEW_COLUMN = "component_uuid";
private static final String INDEX = "properties_component_uuid";

public AddComponentUuidColumnToProperties(Database db) {
super(db);
@@ -41,19 +39,11 @@ public class AddComponentUuidColumnToProperties extends DdlChange {
public void execute(Context context) throws SQLException {
VarcharColumnDef column = newVarcharColumnDefBuilder()
.setColumnName(NEW_COLUMN)
.setLimit(50)
.setLimit(VarcharColumnDef.UUID_SIZE)
.setIsNullable(true)
.build();
context.execute(new AddColumnsBuilder(getDialect(), TABLE)
.addColumn(column)
.build());

CreateIndexBuilder builder = new CreateIndexBuilder()
.setTable(TABLE)
.addColumn(column)
.setName(INDEX)
.setUnique(false);

context.execute(builder.build());
}
}

+ 3
- 3
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/AddComponentUuidColumnToUserRoles.java View File

@@ -41,18 +41,18 @@ public class AddComponentUuidColumnToUserRoles extends DdlChange {
public void execute(Context context) throws SQLException {
VarcharColumnDef column = newVarcharColumnDefBuilder()
.setColumnName(NEW_COLUMN)
.setLimit(50)
.setLimit(VarcharColumnDef.UUID_SIZE)
.setIsNullable(true)
.build();
context.execute(new AddColumnsBuilder(getDialect(), TABLE)
.addColumn(column)
.build());

CreateIndexBuilder index1 = new CreateIndexBuilder()
CreateIndexBuilder index = new CreateIndexBuilder()
.setTable(TABLE)
.addColumn(column)
.setName(INDEX)
.setUnique(false);
context.execute(index1.build());
context.execute(index.build());
}
}

+ 7
- 5
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/DropIdFromComponentsTable.java View File

@@ -22,22 +22,24 @@ package org.sonar.server.platform.db.migration.version.v83;
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.sql.DropConstraintBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
import org.sonar.server.platform.db.migration.version.v83.util.DropPrimaryKeySqlGenerator;

public class DropIdFromComponentsTable extends DdlChange {

static final String ORIGINAL_TABLE_NAME = "projects";
static final String TABLE_NAME = "components";
static final String INDEX_NAME = "pk_projects";
static final String COLUMN_NAME = "id";

public DropIdFromComponentsTable(Database db) {
private final DropPrimaryKeySqlGenerator dropPrimaryKeySqlGenerator;

public DropIdFromComponentsTable(Database db, DropPrimaryKeySqlGenerator dropPrimaryKeySqlGenerator) {
super(db);
this.dropPrimaryKeySqlGenerator = dropPrimaryKeySqlGenerator;
}
@Override
public void execute(Context context) throws SQLException {

context.execute(new DropConstraintBuilder(getDialect()).setTable(TABLE_NAME).setName(INDEX_NAME).build());
context.execute(dropPrimaryKeySqlGenerator.generate(TABLE_NAME, ORIGINAL_TABLE_NAME, COLUMN_NAME));
context.execute(new DropColumnsBuilder(getDialect(), TABLE_NAME, COLUMN_NAME).build());
}
}

+ 18
- 1
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/DropResourceIdFromGroupRolesTable.java View File

@@ -21,14 +21,21 @@ package org.sonar.server.platform.db.migration.version.v83;

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.CreateIndexBuilder;
import org.sonar.server.platform.db.migration.sql.DropColumnsBuilder;
import org.sonar.server.platform.db.migration.sql.DropIndexBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;

import static org.sonar.server.platform.db.migration.def.IntegerColumnDef.newIntegerColumnDefBuilder;
import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;

public class DropResourceIdFromGroupRolesTable extends DdlChange {

static final String TABLE = "group_roles";
static final String COLUMN = "resource_id";
static final String INDEX = "uniq_group_roles";


public DropResourceIdFromGroupRolesTable(Database db) {
super(db);
@@ -36,8 +43,18 @@ public class DropResourceIdFromGroupRolesTable extends DdlChange {

@Override
public void execute(Context context) throws SQLException {
context.execute(new DropIndexBuilder(getDialect()).setTable(TABLE).setName("uniq_group_roles").build());
context.execute(new DropIndexBuilder(getDialect()).setTable(TABLE).setName(INDEX).build());
context.execute(new DropIndexBuilder(getDialect()).setTable(TABLE).setName("group_roles_resource").build());
context.execute(new DropColumnsBuilder(getDialect(), TABLE, COLUMN).build());

CreateIndexBuilder index = new CreateIndexBuilder()
.setTable(TABLE)
.addColumn(newVarcharColumnDefBuilder().setColumnName("organization_uuid").setLimit(VarcharColumnDef.UUID_SIZE).build())
.addColumn(newIntegerColumnDefBuilder().setColumnName("group_id").build())
.addColumn(newVarcharColumnDefBuilder().setColumnName("component_uuid").setLimit(VarcharColumnDef.UUID_SIZE).build())
.addColumn(newVarcharColumnDefBuilder().setColumnName("role").setLimit(64).build())
.setName(INDEX)
.setUnique(true);
context.execute(index.build());
}
}

+ 7
- 11
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/MigrateResourceIdToUuidInGroupRoles.java View File

@@ -31,25 +31,21 @@ public class MigrateResourceIdToUuidInGroupRoles extends DataChange {

@Override protected void execute(Context context) throws SQLException {
// remove roles associated with invalid resource
context.prepareUpsert(
"delete from group_roles gp where gp.resource_id is not null "
+ "and not exists (select 1 from components c where gp.resource_id = c.id)")
context.prepareUpsert("delete from group_roles "
+ "where group_roles.resource_id is not null and not exists (select 1 from components c where group_roles.resource_id = c.id)")
.execute();

MassUpdate massUpdate = context.prepareMassUpdate();
massUpdate.select("select gp.id as gp_id, c.uuid as c_uuid from group_roles gp left join components c on gp.resource_id = c.id");
massUpdate.select("select gp.id as gp_id, c.uuid as c_uuid from group_roles gp, components c where gp.resource_id = c.id and gp.component_uuid is null");
massUpdate.update("update group_roles set component_uuid = ? where id = ?");

massUpdate.execute((row, update) -> {
String componentUuid = row.getString(2);
if (componentUuid != null) {
Long propertyId = row.getLong(1);
Long propertyId = row.getLong(1);

update.setString(1, componentUuid)
.setLong(2, propertyId);
return true;
}
return false;
update.setString(1, componentUuid)
.setLong(2, propertyId);
return true;
});
}
}

+ 6
- 11
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/MigrateResourceIdToUuidInProperties.java View File

@@ -31,26 +31,21 @@ public class MigrateResourceIdToUuidInProperties extends DataChange {

@Override protected void execute(Context context) throws SQLException {
// remove properties associated with invalid resource
context.prepareUpsert(
"delete from properties p where p.resource_id is not null "
+ "and not exists (select 1 from components c where p.resource_id = c.id)")
context.prepareUpsert("delete from properties where properties.resource_id is not null and not exists (select 1 from components c where properties.resource_id = c.id)")
.execute();

MassUpdate massUpdate = context.prepareMassUpdate();

massUpdate.select("select p.id as p_id, c.uuid as c_uuid from properties p left join components c on p.resource_id = c.id");
massUpdate.select("select p.id as p_id, c.uuid as c_uuid from properties p, components c where p.resource_id = c.id and p.component_uuid is null");
massUpdate.update("update properties set component_uuid = ? where id = ?");

massUpdate.execute((row, update) -> {
String componentUuid = row.getString(2);
if (componentUuid != null) {
Long propertyId = row.getLong(1);
Long propertyId = row.getLong(1);

update.setString(1, componentUuid)
.setLong(2, propertyId);
return true;
}
return false;
update.setString(1, componentUuid)
.setLong(2, propertyId);
return true;
});
}
}

+ 6
- 10
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/MigrateResourceIdToUuidInUserRoles.java View File

@@ -32,25 +32,21 @@ public class MigrateResourceIdToUuidInUserRoles extends DataChange {
@Override protected void execute(Context context) throws SQLException {
// remove roles associated with invalid resource
context.prepareUpsert(
"delete from user_roles ur where ur.resource_id is not null "
+ "and not exists (select 1 from components c where ur.resource_id = c.id)")
"delete from user_roles where user_roles.resource_id is not null and not exists (select 1 from components c where user_roles.resource_id = c.id)")
.execute();

MassUpdate massUpdate = context.prepareMassUpdate();

massUpdate.select("select ur.id as ur_id, c.uuid as c_uuid from user_roles ur left join components c on ur.resource_id = c.id");
massUpdate.select("select ur.id as ur_id, c.uuid as c_uuid from user_roles ur, components c where ur.resource_id = c.id and ur.component_uuid is null");
massUpdate.update("update user_roles set component_uuid = ? where id = ?");

massUpdate.execute((row, update) -> {
String componentUuid = row.getString(2);
if (componentUuid != null) {
Long id = row.getLong(1);
Long id = row.getLong(1);

update.setString(1, componentUuid)
.setLong(2, id);
return true;
}
return false;
update.setString(1, componentUuid)
.setLong(2, id);
return true;
});
}
}

+ 87
- 0
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/util/DropPrimaryKeySqlGenerator.java View File

@@ -0,0 +1,87 @@
/*
* 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.util;

import java.sql.SQLException;
import java.util.List;
import org.sonar.db.Database;
import org.sonar.db.dialect.Dialect;
import org.sonar.db.dialect.H2;
import org.sonar.db.dialect.MsSql;
import org.sonar.db.dialect.Oracle;
import org.sonar.db.dialect.PostgreSql;

import static java.lang.String.format;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static java.util.Locale.ENGLISH;
import static org.sonar.server.platform.db.migration.sql.CreateTableBuilder.PRIMARY_KEY_PREFIX;

public class DropPrimaryKeySqlGenerator {
private final Database db;
private final GetConstraintHelper getConstraintHelper;

public DropPrimaryKeySqlGenerator(Database db, GetConstraintHelper getConstraintHelper) {
this.db = db;
this.getConstraintHelper = getConstraintHelper;
}

public List<String> generate(String tableName, String originalTableName, String columnName) throws SQLException {
Dialect dialect = db.getDialect();
switch (dialect.getId()) {
case PostgreSql.ID:
return generateForPostgresSql(tableName, originalTableName, columnName, getConstraintHelper.getPostgresSqlConstraint(tableName));
case MsSql.ID:
return generateForMsSql(tableName, getConstraintHelper.getMssqlConstraint(tableName));
case Oracle.ID:
return generateForOracle(tableName, getConstraintHelper.getOracleConstraint(tableName));
case H2.ID:
return generateForH2(tableName, originalTableName, columnName);
default:
throw new IllegalStateException(format("Unsupported database '%s'", dialect.getId()));
}
}

private static List<String> generateForPostgresSql(String tableName, String originalTableName, String column, String constraintName) {
return asList(
format("ALTER TABLE %s ALTER COLUMN %s DROP DEFAULT", tableName, column),
format("DROP SEQUENCE %s_%s_seq", originalTableName, column),
format("ALTER TABLE %s DROP CONSTRAINT %s", tableName, constraintName));
}

private static List<String> generateForOracle(String tableName, String constraintName) {
return asList(
format("DROP TRIGGER %s_IDT", tableName),
format("DROP SEQUENCE %s_SEQ", tableName),
format("ALTER TABLE %s DROP CONSTRAINT %s", tableName, constraintName));
}

private static List<String> generateForMsSql(String tableName, String constraintName) {
return singletonList(format("ALTER TABLE %s DROP CONSTRAINT %s", tableName, constraintName));
}

private static List<String> generateForH2(String tableName, String originalTableName, String column) {
return asList(
format("ALTER TABLE %s DROP CONSTRAINT %s%s", tableName, PRIMARY_KEY_PREFIX.toUpperCase(ENGLISH), originalTableName),
format("ALTER TABLE %s ALTER COLUMN %s INTEGER NOT NULL", tableName, column));
}

}

+ 104
- 0
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/util/GetConstraintHelper.java View File

@@ -0,0 +1,104 @@
/*
* 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.util;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Locale;
import org.sonar.db.Database;

import static java.lang.String.format;

public class GetConstraintHelper {

private final Database db;

public GetConstraintHelper(Database db) {
this.db = db;
}

String getH2Constraint(String tableName) throws SQLException {
try (Connection connection = db.getDataSource().getConnection();
PreparedStatement pstmt = connection
.prepareStatement(format("SELECT constraint_name "
+ "FROM information_schema.constraints "
+ "WHERE table_name = '%s' and constraint_type = 'PRIMARY KEY'", tableName.toUpperCase(Locale.ENGLISH)));
ResultSet rs = pstmt.executeQuery()) {
if (rs.next()) {
return rs.getString(1);
}
throw contraintNotFoundException(tableName);
}
}

String getPostgresSqlConstraint(String tableName) throws SQLException {
try (Connection connection = db.getDataSource().getConnection();
PreparedStatement pstmt = connection
.prepareStatement(format("SELECT conname " +
"FROM pg_constraint " +
"WHERE conrelid = " +
" (SELECT oid " +
" FROM pg_class " +
" WHERE relname LIKE '%s')", tableName));
ResultSet rs = pstmt.executeQuery()) {
if (rs.next()) {
return rs.getString(1);
}
throw contraintNotFoundException(tableName);
}
}

String getOracleConstraint(String tableName) throws SQLException {
try (Connection connection = db.getDataSource().getConnection();
PreparedStatement pstmt = connection
.prepareStatement(format("SELECT constraint_name " +
"FROM user_constraints " +
"WHERE table_name = UPPER('%s') " +
"AND constraint_type='P'", tableName));
ResultSet rs = pstmt.executeQuery()) {
if (rs.next()) {
return rs.getString(1);
}
throw contraintNotFoundException(tableName);
}
}

String getMssqlConstraint(String tableName) throws SQLException {
try (Connection connection = db.getDataSource().getConnection();
PreparedStatement pstmt = connection
.prepareStatement(format("SELECT name " +
"FROM sys.key_constraints " +
"WHERE type = 'PK' " +
"AND OBJECT_NAME(parent_object_id) = '%s'", tableName));
ResultSet rs = pstmt.executeQuery()) {
if (rs.next()) {
return rs.getString(1);
}
throw contraintNotFoundException(tableName);
}
}

private static IllegalStateException contraintNotFoundException(String tableName) {
return new IllegalStateException(format("Cannot find constraint for table '%s'", tableName));
}

}

+ 1
- 7
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/MigrationConfigurationModuleTest.java View File

@@ -23,7 +23,6 @@ import org.junit.Test;
import org.sonar.core.platform.ComponentContainer;

import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.core.platform.ComponentContainer.COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER;

public class MigrationConfigurationModuleTest {
private MigrationConfigurationModule underTest = new MigrationConfigurationModule();
@@ -34,12 +33,7 @@ public class MigrationConfigurationModuleTest {

underTest.configure(container);

assertThat(container.getPicoContainer().getComponentAdapters())
.hasSize(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER
// DbVersion classes
+ 5
// Others
+ 4);
assertThat(container.getPicoContainer().getComponentAdapters()).isNotEmpty();
}

}

+ 1
- 2
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/AddComponentUuidColumnToGroupRolesTest.java View File

@@ -41,8 +41,7 @@ public class AddComponentUuidColumnToGroupRolesTest {
public void column_has_been_created() throws SQLException {
underTest.execute();
dbTester.assertTableExists(TABLE_NAME);
dbTester.assertColumnDefinition(TABLE_NAME, "component_uuid", VARCHAR, 50, true);
dbTester.assertUniqueIndex(TABLE_NAME, "group_roles_uniq", "organization_uuid", "group_id", "component_uuid", "role");
dbTester.assertColumnDefinition(TABLE_NAME, "component_uuid", VARCHAR, 40, true);
dbTester.assertIndex(TABLE_NAME, "group_roles_component_uuid", "component_uuid");
}


+ 1
- 1
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/AddComponentUuidColumnToPropertiesTest.java View File

@@ -41,7 +41,7 @@ public class AddComponentUuidColumnToPropertiesTest {
public void column_has_been_created() throws SQLException {
underTest.execute();
dbTester.assertTableExists(TABLE_NAME);
dbTester.assertColumnDefinition(TABLE_NAME, "component_uuid", VARCHAR, 50, true);
dbTester.assertColumnDefinition(TABLE_NAME, "component_uuid", VARCHAR, 40, true);
}

}

+ 1
- 1
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/AddComponentUuidColumnToUserRolesTest.java View File

@@ -41,7 +41,7 @@ public class AddComponentUuidColumnToUserRolesTest {
public void column_has_been_created() throws SQLException {
underTest.execute();
dbTester.assertTableExists(TABLE_NAME);
dbTester.assertColumnDefinition(TABLE_NAME, "component_uuid", VARCHAR, 50, true);
dbTester.assertColumnDefinition(TABLE_NAME, "component_uuid", VARCHAR, 40, true);
dbTester.assertIndex(TABLE_NAME, "user_roles_component_uuid", "component_uuid");
}


+ 4
- 4
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/DropIdFromComponentsTableTest.java View File

@@ -24,10 +24,11 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.db.CoreDbTester;
import org.sonar.server.platform.db.migration.version.v83.util.DropPrimaryKeySqlGenerator;
import org.sonar.server.platform.db.migration.version.v83.util.GetConstraintHelper;

import static java.sql.Types.INTEGER;
import static org.sonar.server.platform.db.migration.version.v83.DropIdFromComponentsTable.COLUMN_NAME;
import static org.sonar.server.platform.db.migration.version.v83.DropIdFromComponentsTable.INDEX_NAME;
import static org.sonar.server.platform.db.migration.version.v83.DropIdFromComponentsTable.TABLE_NAME;

public class DropIdFromComponentsTableTest {
@@ -36,14 +37,13 @@ public class DropIdFromComponentsTableTest {
@Rule
public ExpectedException expectedException = ExpectedException.none();

private DropIdFromComponentsTable underTest = new DropIdFromComponentsTable(dbTester.database());
private DropPrimaryKeySqlGenerator dropPrimaryKeySqlGenerator = new DropPrimaryKeySqlGenerator(dbTester.database(), new GetConstraintHelper(dbTester.database()));
private DropIdFromComponentsTable underTest = new DropIdFromComponentsTable(dbTester.database(), dropPrimaryKeySqlGenerator);

@Test
public void column_has_been_dropped() throws SQLException {
dbTester.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, INTEGER, null, false);
underTest.execute();
dbTester.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME);
dbTester.assertIndexDoesNotExist(TABLE_NAME, INDEX_NAME);

}
}

+ 4
- 4
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/DropResourceIdFromGroupRolesTableTest.java View File

@@ -40,12 +40,12 @@ public class DropResourceIdFromGroupRolesTableTest {
@Test
public void column_has_been_dropped() throws SQLException {
dbTester.assertColumnDefinition(TABLE_NAME, "resource_id", INTEGER, null, true);
dbTester.assertUniqueIndex(TABLE_NAME, "UNIQ_GROUP_ROLES", "organization_uuid", "group_id", "resource_id", "role");
dbTester.assertIndex(TABLE_NAME, "GROUP_ROLES_RESOURCE", "resource_id");
dbTester.assertUniqueIndex(TABLE_NAME, "uniq_group_roles", "organization_uuid", "group_id", "resource_id", "role");
dbTester.assertIndex(TABLE_NAME, "group_roles_resource", "resource_id");

underTest.execute();
dbTester.assertColumnDoesNotExist(TABLE_NAME, "resource_id");
dbTester.assertIndexDoesNotExist(TABLE_NAME, "UNIQ_GROUP_ROLES");
dbTester.assertIndexDoesNotExist(TABLE_NAME, "GROUP_ROLES_RESOURCE");
dbTester.assertIndexDoesNotExist(TABLE_NAME, "group_roles_resource");
dbTester.assertUniqueIndex(TABLE_NAME, "uniq_group_roles", "organization_uuid", "group_id", "component_uuid", "role");
}
}

+ 3
- 0
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/MigrateResourceIdToUuidInGroupRolesTest.java View File

@@ -55,6 +55,9 @@ public class MigrateResourceIdToUuidInGroupRolesTest {
.collect(Collectors.toList())).containsExactlyInAnyOrder(
new Tuple(1L, 1L, "uuid1", 1L),
new Tuple(3L, null, null, 1L));

// reentrant
underTest.execute();
}

private void insertRole(@Nullable Integer resourceId) {

+ 2
- 0
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/MigrateResourceIdToUuidInPropertiesTest.java View File

@@ -56,6 +56,8 @@ public class MigrateResourceIdToUuidInPropertiesTest {
new Tuple(1L, 1L, "uuid1", "key", "value"),
new Tuple(3L, null, null, "key", "value"));

// reentrant
underTest.execute();
}

private void insertProperty(@Nullable Integer resourceId) {

+ 3
- 0
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/MigrateResourceIdToUuidInUserRolesTest.java View File

@@ -55,6 +55,9 @@ public class MigrateResourceIdToUuidInUserRolesTest {
.collect(Collectors.toList())).containsExactlyInAnyOrder(
new Tuple(1L, 1L, "uuid1", 1L),
new Tuple(3L, null, null, 1L));

// reentrant
underTest.execute();
}

private void insertRole(@Nullable Integer resourceId) {

+ 96
- 0
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/util/DropPrimaryKeySqlGeneratorTest.java View File

@@ -0,0 +1,96 @@
/*
* 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.util;

import java.sql.SQLException;
import java.util.List;
import org.junit.Test;
import org.sonar.db.Database;
import org.sonar.db.dialect.H2;
import org.sonar.db.dialect.MsSql;
import org.sonar.db.dialect.Oracle;
import org.sonar.db.dialect.PostgreSql;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class DropPrimaryKeySqlGeneratorTest {

private static final String TABLE_NAME = "issues";
private static final String ORIGINAL_TABLE_NAME = "original_issues";
private static final String PK_COLUMN = "id";
private static final String CONSTRAINT = "pk_id";

private static final PostgreSql POSTGRESQL = new PostgreSql();
private static final MsSql MS_SQL = new MsSql();
private static final Oracle ORACLE = new Oracle();
private static final org.sonar.db.dialect.H2 H2 = new H2();

private Database db = mock(Database.class);
private GetConstraintHelper getConstraintHelper = mock(GetConstraintHelper.class);

private DropPrimaryKeySqlGenerator underTest = new DropPrimaryKeySqlGenerator(db, getConstraintHelper);

@Test
public void generate_for_postgres_sql() throws SQLException {
when(getConstraintHelper.getPostgresSqlConstraint(TABLE_NAME)).thenReturn(CONSTRAINT);
when(db.getDialect()).thenReturn(POSTGRESQL);

List<String> sqls = underTest.generate(TABLE_NAME, ORIGINAL_TABLE_NAME, PK_COLUMN);

assertThat(sqls).containsExactly("ALTER TABLE issues ALTER COLUMN id DROP DEFAULT",
"DROP SEQUENCE original_issues_id_seq",
"ALTER TABLE issues DROP CONSTRAINT pk_id");
}

@Test
public void generate_for_ms_sql() throws SQLException {
when(getConstraintHelper.getMssqlConstraint(TABLE_NAME)).thenReturn(CONSTRAINT);
when(db.getDialect()).thenReturn(MS_SQL);

List<String> sqls = underTest.generate(TABLE_NAME, ORIGINAL_TABLE_NAME, PK_COLUMN);

assertThat(sqls).containsExactly("ALTER TABLE issues DROP CONSTRAINT pk_id");
}

@Test
public void generate_for_oracle() throws SQLException {
when(getConstraintHelper.getOracleConstraint(TABLE_NAME)).thenReturn(CONSTRAINT);
when(db.getDialect()).thenReturn(ORACLE);

List<String> sqls = underTest.generate(TABLE_NAME, ORIGINAL_TABLE_NAME, PK_COLUMN);

assertThat(sqls).containsExactly("DROP TRIGGER issues_IDT",
"DROP SEQUENCE issues_SEQ",
"ALTER TABLE issues DROP CONSTRAINT pk_id");
}

@Test
public void generate_for_h2() throws SQLException {
when(getConstraintHelper.getH2Constraint(TABLE_NAME)).thenReturn(CONSTRAINT);
when(db.getDialect()).thenReturn(H2);

List<String> sqls = underTest.generate(TABLE_NAME, ORIGINAL_TABLE_NAME, PK_COLUMN);

assertThat(sqls).containsExactly("ALTER TABLE issues DROP CONSTRAINT PK_original_issues",
"ALTER TABLE issues ALTER COLUMN id INTEGER NOT NULL");
}
}

+ 0
- 1
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/DropResourceIdFromGroupRolesTableTest/schema.sql View File

@@ -8,6 +8,5 @@ CREATE TABLE "GROUP_ROLES"(
);
ALTER TABLE "GROUP_ROLES" ADD CONSTRAINT "PK_GROUP_ROLES" PRIMARY KEY("ID");
CREATE UNIQUE INDEX "UNIQ_GROUP_ROLES" ON "GROUP_ROLES"("ORGANIZATION_UUID", "GROUP_ID", "RESOURCE_ID", "ROLE");
CREATE UNIQUE INDEX "GROUP_ROLES_UNIQ" ON "GROUP_ROLES"("ORGANIZATION_UUID", "GROUP_ID", "COMPONENT_UUID", "ROLE");
CREATE INDEX "GROUP_ROLES_RESOURCE" ON "GROUP_ROLES"("RESOURCE_ID");
CREATE INDEX "GROUP_ROLES_COMPONENT_UUID" ON "GROUP_ROLES"("COMPONENT_UUID");

+ 0
- 1
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/DropResourceIdFromPropertiesTableTest/schema.sql View File

@@ -11,4 +11,3 @@ CREATE TABLE "PROPERTIES"(
);
ALTER TABLE "PROPERTIES" ADD CONSTRAINT "PK_PROPERTIES" PRIMARY KEY("ID");
CREATE INDEX "PROPERTIES_KEY" ON "PROPERTIES"("PROP_KEY");
CREATE INDEX "PROPERTIES_COMPONENT_UUID" ON "PROPERTIES"("COMPONENT_UUID");

+ 0
- 1
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/MigrateResourceIdToUuidInPropertiesTest/schema.sql View File

@@ -11,7 +11,6 @@ CREATE TABLE "PROPERTIES"(
);
ALTER TABLE "PROPERTIES" ADD CONSTRAINT "PK_PROPERTIES" PRIMARY KEY("ID");
CREATE INDEX "PROPERTIES_KEY" ON "PROPERTIES"("PROP_KEY");
CREATE INDEX "PROPERTIES_COMPONENT_UUID" ON "PROPERTIES"("COMPONENT_UUID");

CREATE TABLE "COMPONENTS"(
"ID" INTEGER NOT NULL AUTO_INCREMENT (1,1),

+ 1
- 1
server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/ws/ProjectStatusAction.java View File

@@ -100,7 +100,7 @@ public class ProjectStatusAction implements QualityGatesWsAction {

action.createParam(PARAM_PROJECT_ID)
.setSince("5.4")
.setDescription("Project id. Doesn't work with branches or pull requests")
.setDescription("Project UUID. Doesn't work with branches or pull requests")
.setExampleValue(Uuids.UUID_EXAMPLE_01);

action.createParam(PARAM_PROJECT_KEY)

Loading…
Cancel
Save