From: Julien HENRY Date: Mon, 3 Dec 2018 15:56:30 +0000 (+0100) Subject: SONAR-11463 Don't migrate root folders and fix component key migration X-Git-Tag: 7.6~85 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=3a9fc2f40564404749d501d354b79a91e3df3a49;p=sonarqube.git SONAR-11463 Don't migrate root folders and fix component key migration --- diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/ComponentUuidFactory.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/ComponentUuidFactory.java index 11459ba43a7..ccd812b6f14 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/ComponentUuidFactory.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/ComponentUuidFactory.java @@ -23,10 +23,12 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.function.Supplier; import java.util.stream.Collectors; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; import org.apache.commons.lang.StringUtils; import org.sonar.api.resources.Qualifiers; +import org.sonar.api.resources.Scopes; import org.sonar.core.component.ComponentKeys; import org.sonar.core.util.Uuids; import org.sonar.db.DbClient; @@ -38,28 +40,65 @@ import org.sonar.db.component.KeyWithUuidDto; public class ComponentUuidFactory { private final Map uuidsByKey = new HashMap<>(); - public ComponentUuidFactory(DbClient dbClient, DbSession dbSession, String rootKey, Supplier> reportModulesPath) { - Map modulePathsByUuid = loadModulePathsByUuid(dbClient, dbSession, rootKey, reportModulesPath); + public ComponentUuidFactory(DbClient dbClient, DbSession dbSession, String rootKey, Map reportModulesPath) { + Map modulePathsByUuid; - if (modulePathsByUuid.isEmpty()) { - // only contains root project or we don't have relative paths for other modules anyway - List keys = dbClient.componentDao().selectUuidsByKeyFromProjectKey(dbSession, rootKey); - keys.forEach(dto -> uuidsByKey.put(dto.key(), dto.uuid())); + if (reportModulesPath.isEmpty()) { + noMigration(dbClient, dbSession, rootKey); } else { - List dtos = loadComponentsWithModuleUuid(dbClient, dbSession, rootKey); - for (ComponentWithModuleUuidDto dto : dtos) { - String pathFromRootProject = modulePathsByUuid.get(dto.moduleUuid()); - String componentPath = StringUtils.isEmpty(pathFromRootProject) ? dto.path() : (pathFromRootProject + "/" + dto.path()); + modulePathsByUuid = loadModulePathsByUuid(dbClient, dbSession, rootKey, reportModulesPath); + + if (modulePathsByUuid.isEmpty()) { + noMigration(dbClient, dbSession, rootKey); + } else { + doMigration(dbClient, dbSession, rootKey, modulePathsByUuid); + } + } + } + + private void noMigration(DbClient dbClient, DbSession dbSession, String rootKey) { + List keys = dbClient.componentDao().selectUuidsByKeyFromProjectKey(dbSession, rootKey); + keys.forEach(dto -> uuidsByKey.put(dto.key(), dto.uuid())); + } + + private void doMigration(DbClient dbClient, DbSession dbSession, String rootKey, Map modulePathsByUuid) { + List dtos = loadComponentsWithModuleUuid(dbClient, dbSession, rootKey); + for (ComponentWithModuleUuidDto dto : dtos) { + if ("/".equals(dto.path())) { + // skip root folders + continue; + } + + if (Scopes.PROJECT.equals(dto.scope())) { + String modulePathFromRootProject = modulePathsByUuid.get(dto.uuid()); + uuidsByKey.put(ComponentKeys.createEffectiveKey(rootKey, modulePathFromRootProject), dto.uuid()); + } else { + String modulePathFromRootProject = modulePathsByUuid.get(dto.moduleUuid()); + String componentPath = createComponentPath(dto, modulePathFromRootProject); uuidsByKey.put(ComponentKeys.createEffectiveKey(rootKey, componentPath), dto.uuid()); } } } + @CheckForNull + private static String createComponentPath(ComponentWithModuleUuidDto dto, @Nullable String modulePathFromRootProject) { + if (StringUtils.isEmpty(modulePathFromRootProject)) { + return dto.path(); + } + + if (StringUtils.isEmpty(dto.path())) { + // will be the case for modules + return modulePathFromRootProject; + } + + return modulePathFromRootProject + "/" + dto.path(); + } + private static List loadComponentsWithModuleUuid(DbClient dbClient, DbSession dbSession, String rootKey) { return dbClient.componentDao().selectComponentsWithModuleUuidFromProjectKey(dbSession, rootKey); } - private static Map loadModulePathsByUuid(DbClient dbClient, DbSession dbSession, String rootKey, Supplier> reportModulesPath) { + private static Map loadModulePathsByUuid(DbClient dbClient, DbSession dbSession, String rootKey, Map pathByModuleKey) { List moduleDtos = dbClient.componentDao() .selectModulesFromProjectKey(dbSession, rootKey, false).stream() .filter(c -> Qualifiers.MODULE.equals(c.qualifier())) @@ -69,7 +108,6 @@ public class ComponentUuidFactory { return Collections.emptyMap(); } - Map pathByModuleKey = reportModulesPath.get(); Map modulePathByUuid = new HashMap<>(); for (ComponentDto dto : moduleDtos) { String relativePath = pathByModuleKey.get(dto.getKey()); diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/BuildComponentTreeStep.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/BuildComponentTreeStep.java index b1511df95ab..9bd4a18fac5 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/BuildComponentTreeStep.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/BuildComponentTreeStep.java @@ -79,7 +79,7 @@ public class BuildComponentTreeStep implements ComputationStep { String rootKey = keyGenerator.generateKey(reportProject, null); // loads the UUIDs from database. If they don't exist, then generate new ones - ComponentUuidFactory componentUuidFactory = new ComponentUuidFactory(dbClient, dbSession, rootKey, reportModulesPath); + ComponentUuidFactory componentUuidFactory = new ComponentUuidFactory(dbClient, dbSession, rootKey, reportModulesPath.get()); String rootUuid = componentUuidFactory.getOrCreateForKey(rootKey); SnapshotDto baseAnalysis = loadBaseAnalysis(dbSession, rootUuid); diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistComponentsStep.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistComponentsStep.java index 64c7c45b838..9ee2cc9c165 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistComponentsStep.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistComponentsStep.java @@ -100,16 +100,16 @@ public class PersistComponentsStep implements ComputationStep { // safeguard, reset all rows to b-changed=false dbClient.componentDao().resetBChangedForRootComponentUuid(dbSession, projectUuid); - Map existingDtosByKeys = indexExistingDtosByKey(dbSession); - boolean isRootPrivate = isRootPrivate(treeRootHolder.getRoot(), existingDtosByKeys); + Map existingDtosByUuids = indexExistingDtosByUuids(dbSession); + boolean isRootPrivate = isRootPrivate(treeRootHolder.getRoot(), existingDtosByUuids); String mainBranchProjectUuid = loadProjectUuidOfMainBranch(); - // Insert or update the components in database. They are removed from existingDtosByKeys + // Insert or update the components in database. They are removed from existingDtosByUuids // at the same time. - new PathAwareCrawler<>(new PersistComponentStepsVisitor(existingDtosByKeys, dbSession, mainBranchProjectUuid)) + new PathAwareCrawler<>(new PersistComponentStepsVisitor(existingDtosByUuids, dbSession, mainBranchProjectUuid)) .visit(treeRootHolder.getRoot()); - disableRemainingComponents(dbSession, existingDtosByKeys.values()); + disableRemainingComponents(dbSession, existingDtosByUuids.values()); ensureConsistentVisibility(dbSession, projectUuid, isRootPrivate); dbSession.commit(); @@ -141,14 +141,13 @@ public class PersistComponentsStep implements ComputationStep { dbClient.componentDao().setPrivateForRootComponentUuid(dbSession, projectUuid, isRootPrivate); } - private static boolean isRootPrivate(Component root, Map existingDtosByKeys) { - String rootKey = root.getDbKey(); - ComponentDto rootDto = existingDtosByKeys.get(rootKey); + private static boolean isRootPrivate(Component root, Map existingDtosByUuids) { + ComponentDto rootDto = existingDtosByUuids.get(root.getUuid()); if (rootDto == null) { if (Component.Type.VIEW == root.getType()) { return false; } - throw new IllegalStateException(String.format("The project '%s' is not stored in the database, during a project analysis.", rootKey)); + throw new IllegalStateException(String.format("The project '%s' is not stored in the database, during a project analysis.", root.getDbKey())); } return rootDto.isPrivate(); } @@ -157,20 +156,20 @@ public class PersistComponentsStep implements ComputationStep { * Returns a mutable map of the components currently persisted in database for the project, including * disabled components. */ - private Map indexExistingDtosByKey(DbSession session) { + private Map indexExistingDtosByUuids(DbSession session) { return dbClient.componentDao().selectAllComponentsFromProjectKey(session, treeRootHolder.getRoot().getDbKey()) .stream() - .collect(Collectors.toMap(ComponentDto::getDbKey, Function.identity())); + .collect(Collectors.toMap(ComponentDto::uuid, Function.identity())); } private class PersistComponentStepsVisitor extends PathAwareVisitorAdapter { - private final Map existingComponentDtosByKey; + private final Map existingComponentDtosByUuids; private final DbSession dbSession; @Nullable private final String mainBranchProjectUuid; - PersistComponentStepsVisitor(Map existingComponentDtosByKey, DbSession dbSession, @Nullable String mainBranchProjectUuid) { + PersistComponentStepsVisitor(Map existingComponentDtosByUuids, DbSession dbSession, @Nullable String mainBranchProjectUuid) { super( CrawlerDepthLimit.LEAVES, PRE_ORDER, @@ -192,7 +191,7 @@ public class PersistComponentsStep implements ComputationStep { return null; } }); - this.existingComponentDtosByKey = existingComponentDtosByKey; + this.existingComponentDtosByUuids = existingComponentDtosByUuids; this.dbSession = dbSession; this.mainBranchProjectUuid = mainBranchProjectUuid; } @@ -240,7 +239,7 @@ public class PersistComponentsStep implements ComputationStep { } private ComponentDto persistComponent(ComponentDto componentDto) { - ComponentDto existingComponent = existingComponentDtosByKey.remove(componentDto.getDbKey()); + ComponentDto existingComponent = existingComponentDtosByUuids.remove(componentDto.uuid()); if (existingComponent == null) { dbClient.componentDao().insert(dbSession, componentDto); return componentDto; @@ -252,6 +251,7 @@ public class PersistComponentsStep implements ComputationStep { // update the fields in memory in order the PathAwareVisitor.Path // to be up-to-date + existingComponent.setDbKey(updateDto.getBKey()); existingComponent.setCopyComponentUuid(updateDto.getBCopyComponentUuid()); existingComponent.setDescription(updateDto.getBDescription()); existingComponent.setEnabled(updateDto.isBEnabled()); @@ -371,7 +371,6 @@ public class PersistComponentsStep implements ComputationStep { componentDto.setOrganizationUuid(analysisMetadataHolder.getOrganization().getUuid()); componentDto.setUuid(componentUuid); componentDto.setDbKey(componentKey); - componentDto.setDeprecatedKey(componentKey); componentDto.setMainBranchProjectUuid(mainBranchProjectUuid); componentDto.setEnabled(true); componentDto.setCreatedAt(new Date(system2.now())); @@ -415,6 +414,7 @@ public class PersistComponentsStep implements ComputationStep { private static Optional compareForUpdate(ComponentDto existing, ComponentDto target) { boolean hasDifferences = !StringUtils.equals(existing.getCopyResourceUuid(), target.getCopyResourceUuid()) || !StringUtils.equals(existing.description(), target.description()) || + !StringUtils.equals(existing.getDbKey(), target.getDbKey()) || !existing.isEnabled() || !StringUtils.equals(existing.getUuidPath(), target.getUuidPath()) || !StringUtils.equals(existing.language(), target.language()) || diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/ComponentUuidFactoryTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/ComponentUuidFactoryTest.java index 3d84801d17a..76e1acd6d01 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/ComponentUuidFactoryTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/ComponentUuidFactoryTest.java @@ -30,26 +30,21 @@ import org.sonar.db.component.ComponentDto; import org.sonar.db.component.ComponentTesting; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; public class ComponentUuidFactoryTest { @Rule public DbTester db = DbTester.create(System2.INSTANCE); - private ReportModulesPath reportModulesPath = mock(ReportModulesPath.class); - @Test public void load_uuids_from_existing_components_in_db() { ComponentDto project = db.components().insertPrivateProject(); - ComponentDto module = db.components().insertComponent(ComponentTesting - .newModuleDto(project)); - when(reportModulesPath.get()).thenReturn(Collections.singletonMap(module.getKey(), "module1_path")); + ComponentDto module = db.components().insertComponent(ComponentTesting.newModuleDto(project)); + Map reportModulesPath = Collections.singletonMap(module.getKey(), "module1_path"); ComponentUuidFactory underTest = new ComponentUuidFactory(db.getDbClient(), db.getSession(), project.getDbKey(), reportModulesPath); assertThat(underTest.getOrCreateForKey(project.getDbKey())).isEqualTo(project.uuid()); - assertThat(underTest.getOrCreateForKey(module.getDbKey())).isNotEqualTo(module.uuid()); + assertThat(underTest.getOrCreateForKey(module.getDbKey())).isNotIn(project.uuid(), module.uuid()); } @Test @@ -70,8 +65,7 @@ public class ComponentUuidFactoryTest { Map modulesRelativePaths = new HashMap<>(); modulesRelativePaths.put("project:module1", "module1_path"); modulesRelativePaths.put("project:module1:module2", "module1_path/module2_path"); - when(reportModulesPath.get()).thenReturn(modulesRelativePaths); - ComponentUuidFactory underTest = new ComponentUuidFactory(db.getDbClient(), db.getSession(), project.getDbKey(), reportModulesPath); + ComponentUuidFactory underTest = new ComponentUuidFactory(db.getDbClient(), db.getSession(), project.getDbKey(), modulesRelativePaths); // migrated files assertThat(underTest.getOrCreateForKey("project:file1_path")).isEqualTo(file1.uuid()); @@ -81,10 +75,32 @@ public class ComponentUuidFactoryTest { assertThat(underTest.getOrCreateForKey(project.getDbKey())).isEqualTo(project.uuid()); // old keys with modules don't exist - assertThat(underTest.getOrCreateForKey(module1.getDbKey())).isNotEqualTo(module1.uuid()); - assertThat(underTest.getOrCreateForKey(module2.getDbKey())).isNotEqualTo(module2.uuid()); - assertThat(underTest.getOrCreateForKey(file1.getDbKey())).isNotEqualTo(file1.uuid()); - assertThat(underTest.getOrCreateForKey(file2.getDbKey())).isNotEqualTo(file2.uuid()); + assertThat(underTest.getOrCreateForKey(module1.getDbKey())).isNotIn(project.uuid(), module1.uuid(), module2.uuid(), file1.uuid(), file2.uuid()); + assertThat(underTest.getOrCreateForKey(module2.getDbKey())).isNotIn(project.uuid(), module1.uuid(), module2.uuid(), file1.uuid(), file2.uuid()); + assertThat(underTest.getOrCreateForKey(file1.getDbKey())).isNotIn(project.uuid(), module1.uuid(), module2.uuid(), file1.uuid(), file2.uuid()); + assertThat(underTest.getOrCreateForKey(file2.getDbKey())).isNotIn(project.uuid(), module1.uuid(), module2.uuid(), file1.uuid(), file2.uuid()); + } + + @Test + public void migrate_project_with_root_folders() { + ComponentDto project = db.components().insertPrivateProject(dto -> dto.setDbKey("project")); + ComponentDto module1 = db.components().insertComponent(ComponentTesting.newModuleDto(project) + .setDbKey("project:module1")); + ComponentDto dir1 = db.components().insertComponent(ComponentTesting.newDirectory(module1, "/") + .setDbKey("project:module1:/")); + + Map modulesRelativePaths = Collections.singletonMap("project:module1", "module1_path"); + ComponentUuidFactory underTest = new ComponentUuidFactory(db.getDbClient(), db.getSession(), project.getDbKey(), modulesRelativePaths); + + // project remains the same + assertThat(underTest.getOrCreateForKey(project.getDbKey())).isEqualTo(project.uuid()); + + // module migrated to folder + assertThat(underTest.getOrCreateForKey("project:module1_path")).isEqualTo(module1.uuid()); + + // doesnt exist + assertThat(underTest.getOrCreateForKey("project:module1_path/")).isNotIn(project.uuid(), module1.uuid(), dir1.uuid()); + assertThat(underTest.getOrCreateForKey("project:module1")).isNotIn(project.uuid(), module1.uuid(), dir1.uuid()); } @Test @@ -97,18 +113,17 @@ public class ComponentUuidFactoryTest { .setDbKey("project:file1") .setEnabled(false) .setPath("file1_path")); - when(reportModulesPath.get()).thenReturn(Collections.singletonMap("project:module1", "module1_path")); + Map modulesRelativePaths = Collections.singletonMap("project:module1", "module1_path"); - ComponentUuidFactory underTest = new ComponentUuidFactory(db.getDbClient(), db.getSession(), project.getDbKey(), reportModulesPath); + ComponentUuidFactory underTest = new ComponentUuidFactory(db.getDbClient(), db.getSession(), project.getDbKey(), modulesRelativePaths); - // migrated files + // migrated file assertThat(underTest.getOrCreateForKey("project:module1_path/file1_path")).isEqualTo(file1.uuid()); } @Test public void generate_uuid_if_it_does_not_exist_in_db() { - when(reportModulesPath.get()).thenReturn(Collections.emptyMap()); - ComponentUuidFactory underTest = new ComponentUuidFactory(db.getDbClient(), db.getSession(), "theProjectKey", reportModulesPath); + ComponentUuidFactory underTest = new ComponentUuidFactory(db.getDbClient(), db.getSession(), "theProjectKey", Collections.emptyMap()); String generatedKey = underTest.getOrCreateForKey("foo"); assertThat(generatedKey).isNotEmpty(); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDto.java index f0612417e5f..a6c6e823bb3 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDto.java @@ -147,7 +147,6 @@ public class ComponentDto { private String scope; private String qualifier; private String path; - private String deprecatedKey; private String name; private String longName; private String language; @@ -264,16 +263,6 @@ public class ComponentDto { return this; } - @CheckForNull - public String deprecatedKey() { - return deprecatedKey; - } - - public ComponentDto setDeprecatedKey(@Nullable String deprecatedKey) { - this.deprecatedKey = deprecatedKey; - return this; - } - /** * Return the root project uuid. On a root project, return itself */ @@ -483,7 +472,6 @@ public class ComponentDto { .append("mainBranchProjectUuid", mainBranchProjectUuid) .append("copyComponentUuid", copyComponentUuid) .append("path", path) - .append("deprecatedKey", deprecatedKey) .append("name", name) .append("longName", longName) .append("language", language) @@ -509,7 +497,6 @@ public class ComponentDto { copy.scope = scope; copy.qualifier = qualifier; copy.path = path; - copy.deprecatedKey = deprecatedKey; copy.name = name; copy.longName = longName; copy.language = language; diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentUpdateDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentUpdateDto.java index 357f478e61c..1c485731437 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentUpdateDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentUpdateDto.java @@ -30,6 +30,10 @@ public class ComponentUpdateDto { * See https://jira.sonarsource.com/browse/SONAR-7700 */ private boolean bChanged; + /** + * Component keys are normally immutable. But in SQ 7.6 we have to migrate component keys to drop modules. + */ + private String bKey; private String bCopyComponentUuid; private String bDescription; private boolean bEnabled; @@ -55,6 +59,10 @@ public class ComponentUpdateDto { return bChanged; } + public String getBKey() { + return bKey; + } + @CheckForNull public String getBCopyComponentUuid() { return bCopyComponentUuid; @@ -113,6 +121,11 @@ public class ComponentUpdateDto { return this; } + public ComponentUpdateDto setBKey(String s) { + this.bKey = s; + return this; + } + public ComponentUpdateDto setBCopyComponentUuid(@Nullable String s) { this.bCopyComponentUuid = s; return this; @@ -175,6 +188,7 @@ public class ComponentUpdateDto { return new ComponentUpdateDto() .setUuid(from.uuid()) .setBChanged(false) + .setBKey(from.getDbKey()) .setBCopyComponentUuid(from.getCopyResourceUuid()) .setBDescription(from.description()) .setBEnabled(from.isEnabled()) diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentWithModuleUuidDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentWithModuleUuidDto.java index 3c2045f4873..b7157a0840e 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentWithModuleUuidDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentWithModuleUuidDto.java @@ -26,11 +26,13 @@ public class ComponentWithModuleUuidDto { private final String uuid; private final String moduleUuid; private final String path; + private final String scope; - public ComponentWithModuleUuidDto(String uuid, String moduleUuid, String path) { + public ComponentWithModuleUuidDto(String uuid, String moduleUuid, String path, String scope) { this.uuid = uuid; this.moduleUuid = moduleUuid; this.path = path; + this.scope = scope; } public String path() { @@ -44,4 +46,8 @@ public class ComponentWithModuleUuidDto { public String uuid() { return uuid; } + + public String scope() { + return scope; + } } diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml index 919e317a67c..ca0db872a8a 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml @@ -12,7 +12,6 @@ p.module_uuid_path as moduleUuidPath, p.main_branch_project_uuid as mainBranchProjectUuid, p.kee as kee, - p.deprecated_kee as deprecatedKey, p.name as name, p.long_name as longName, p.description as description, @@ -521,7 +520,7 @@