From: Julien Lancelot Date: Thu, 4 Jun 2015 12:11:32 +0000 (+0200) Subject: SONAR-6260 Persist snapshots without periods X-Git-Tag: 5.2-RC1~1549 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=1de5ba33b22003de4247bd2fd0da393cfae7b2f1;p=sonarqube.git SONAR-6260 Persist snapshots without periods --- diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/db/SnapshotDao.java b/server/sonar-server/src/main/java/org/sonar/server/component/db/SnapshotDao.java index e09147b747d..6682f541987 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/component/db/SnapshotDao.java +++ b/server/sonar-server/src/main/java/org/sonar/server/component/db/SnapshotDao.java @@ -50,6 +50,10 @@ public class SnapshotDao implements DaoComponent { return mapper(session).selectLastSnapshot(componentId); } + public List selectSnapshotsByComponentId(DbSession session, long componentId) { + return mapper(session).selectSnapshotsByComponentId(componentId); + } + public List selectSnapshotAndChildrenOfProjectScope(DbSession session, long snapshotId) { return mapper(session).selectSnapshotAndChildrenOfScope(snapshotId, Scopes.PROJECT); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/component/DbIdsRepository.java b/server/sonar-server/src/main/java/org/sonar/server/computation/component/DbIdsRepository.java index a07059b1e43..1d465ba2183 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/component/DbIdsRepository.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/component/DbIdsRepository.java @@ -24,15 +24,12 @@ import java.util.HashMap; import java.util.Map; /** - * Cache of persisted component (component id) that can be used in the persistence steps + * Cache of persisted component (component id and snapshot id) that can be used in the persistence steps */ public class DbIdsRepository { - private final Map componentIdsByRef; - - public DbIdsRepository() { - componentIdsByRef = new HashMap<>(); - } + private final Map componentIdsByRef = new HashMap<>(); + private final Map snapshotIdsByRef = new HashMap<>(); public DbIdsRepository setComponentId(Component component, long componentId) { int ref = component.getRef(); @@ -53,4 +50,23 @@ public class DbIdsRepository { return componentId; } + public DbIdsRepository setSnapshotId(Component component, long snapshotId) { + int ref = component.getRef(); + Long existingSnapshotId = snapshotIdsByRef.get(ref); + if (existingSnapshotId != null) { + throw new IllegalArgumentException(String.format("Component ref '%s' has already a snapshot id", ref)); + } + snapshotIdsByRef.put(ref, snapshotId); + return this; + } + + public long getSnapshotId(Component component) { + int ref = component.getRef(); + Long snapshotId = snapshotIdsByRef.get(ref); + if (snapshotId == null) { + throw new IllegalArgumentException(String.format("Component ref '%s' has no snapshot id", ref)); + } + return snapshotId; + } + } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistComponentsAndSnapshotsStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistComponentsAndSnapshotsStep.java index 844f00e3e2f..206752d756c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistComponentsAndSnapshotsStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistComponentsAndSnapshotsStep.java @@ -52,14 +52,14 @@ public class PersistComponentsAndSnapshotsStep implements ComputationStep { private final TreeRootHolder treeRootHolder; private final BatchReportReader reportReader; - private final DbIdsRepository dbIdsRepositor; + private final DbIdsRepository dbIdsRepository; - public PersistComponentsAndSnapshotsStep(System2 system2, DbClient dbClient, TreeRootHolder treeRootHolder, BatchReportReader reportReader, DbIdsRepository dbIdsRepositor) { + public PersistComponentsAndSnapshotsStep(System2 system2, DbClient dbClient, TreeRootHolder treeRootHolder, BatchReportReader reportReader, DbIdsRepository dbIdsRepository) { this.system2 = system2; this.dbClient = dbClient; this.treeRootHolder = treeRootHolder; this.reportReader = reportReader; - this.dbIdsRepositor = dbIdsRepositor; + this.dbIdsRepository = dbIdsRepository; } @Override @@ -149,7 +149,7 @@ public class PersistComponentsAndSnapshotsStep implements ComputationStep { componentDto.setModuleUuidPath(ComponentDto.MODULE_UUID_PATH_SEP + componentDto.uuid() + ComponentDto.MODULE_UUID_PATH_SEP); ComponentDto projectDto = persistComponent(project.getRef(), componentDto); - SnapshotDto snapshotDto = persistSnapshot(projectDto, reportComponent.getVersion(), null); + SnapshotDto snapshotDto = persistSnapshot(projectDto, projectDto.getId(), reportComponent.getVersion(), null); addToCache(project, projectDto, snapshotDto); @@ -175,7 +175,7 @@ public class PersistComponentsAndSnapshotsStep implements ComputationStep { componentDto.setModuleUuidPath(lastModule.moduleUuidPath() + componentDto.uuid() + ComponentDto.MODULE_UUID_PATH_SEP); ComponentDto moduleDto = persistComponent(module.getRef(), componentDto); - SnapshotDto snapshotDto = persistSnapshot(moduleDto, reportComponent.getVersion(), parentSnapshot); + SnapshotDto snapshotDto = persistSnapshot(moduleDto, project.getId(), reportComponent.getVersion(), parentSnapshot); addToCache(module, moduleDto, snapshotDto); return new PersistedComponent(moduleDto, snapshotDto); @@ -199,7 +199,7 @@ public class PersistComponentsAndSnapshotsStep implements ComputationStep { componentDto.setModuleUuidPath(lastModule.moduleUuidPath()); ComponentDto directoryDto = persistComponent(directory.getRef(), componentDto); - SnapshotDto snapshotDto = persistSnapshot(directoryDto, null, parentSnapshot); + SnapshotDto snapshotDto = persistSnapshot(directoryDto, project.getId(), null, parentSnapshot); addToCache(directory, directoryDto, snapshotDto); return new PersistedComponent(directoryDto, snapshotDto); @@ -226,23 +226,11 @@ public class PersistComponentsAndSnapshotsStep implements ComputationStep { componentDto.setModuleUuidPath(lastModule.moduleUuidPath()); ComponentDto fileDto = persistComponent(file.getRef(), componentDto); - SnapshotDto snapshotDto = persistSnapshot(fileDto, null, parentSnapshot); + SnapshotDto snapshotDto = persistSnapshot(fileDto, project.getId(), null, parentSnapshot); addToCache(file, fileDto, snapshotDto); } - private ComponentDto createComponentDto(BatchReport.Component reportComponent, org.sonar.server.computation.component.Component component) { - String componentKey = component.getKey(); - String componentUuid = component.getUuid(); - - ComponentDto componentDto = new ComponentDto(); - componentDto.setUuid(componentUuid); - componentDto.setKey(componentKey); - componentDto.setDeprecatedKey(componentKey); - componentDto.setEnabled(true); - return componentDto; - } - private ComponentDto persistComponent(int componentRef, ComponentDto componentDto) { ComponentDto existingComponent = componentDtosByKey.get(componentDto.getKey()); if (existingComponent == null) { @@ -256,78 +244,82 @@ public class PersistComponentsAndSnapshotsStep implements ComputationStep { } } - private SnapshotDto persistSnapshot(ComponentDto componentDto, @Nullable String version, @Nullable SnapshotDto parentSnapshot){ - SnapshotDto snapshotDto = new SnapshotDto(); -// .setRootProjectId(project.getId()) -// .setVersion(version) -// .setComponentId(componentDto.getId()) -// .setQualifier(componentDto.qualifier()) -// .setScope(componentDto.scope()) -// .setCreatedAt(analysisDate) -// .setBuildDate(system2.now()); -// -// if (parentSnapshot != null) { -// snapshotDto -// .setParentId(parentSnapshot.getId()) -// .setRootId(parentSnapshot.getRootId() == null ? parentSnapshot.getId() : parentSnapshot.getRootId()) -// .setDepth(parentSnapshot.getDepth() + 1) -// .setPath(parentSnapshot.getPath() + parentSnapshot.getId() + "."); -// } else { -// snapshotDto -// .setPath("") -// .setDepth(0); -// } -// dbClient.snapshotDao().insert(dbSession, snapshotDto); + private SnapshotDto persistSnapshot(ComponentDto componentDto, long projectId, @Nullable String version, @Nullable SnapshotDto parentSnapshot){ + SnapshotDto snapshotDto = new SnapshotDto() + .setRootProjectId(projectId) + .setVersion(version) + .setComponentId(componentDto.getId()) + .setQualifier(componentDto.qualifier()) + .setScope(componentDto.scope()) + .setLast(false) + .setStatus(SnapshotDto.STATUS_UNPROCESSED) + .setCreatedAt(analysisDate) + .setBuildDate(system2.now()); + + if (parentSnapshot != null) { + snapshotDto + .setParentId(parentSnapshot.getId()) + .setRootId(parentSnapshot.getRootId() == null ? parentSnapshot.getId() : parentSnapshot.getRootId()) + .setDepth(parentSnapshot.getDepth() + 1) + .setPath(parentSnapshot.getPath() + parentSnapshot.getId() + "."); + } else { + snapshotDto + .setPath("") + .setDepth(0); + } + dbClient.snapshotDao().insert(dbSession, snapshotDto); return snapshotDto; } private void addToCache(Component component, ComponentDto componentDto, SnapshotDto snapshotDto) { - dbIdsRepositor.setComponentId(component, componentDto.getId()); + dbIdsRepository.setComponentId(component, componentDto.getId()); + dbIdsRepository.setSnapshotId(component, snapshotDto.getId()); } + } - private boolean updateComponent(ComponentDto existingComponent, ComponentDto newComponent) { - boolean isUpdated = false; - if (!StringUtils.equals(existingComponent.name(), newComponent.name())) { - existingComponent.setName(newComponent.name()); - isUpdated = true; - } - if (!StringUtils.equals(existingComponent.description(), newComponent.description())) { - existingComponent.setDescription(newComponent.description()); - isUpdated = true; - } - if (!StringUtils.equals(existingComponent.path(), newComponent.path())) { - existingComponent.setPath(newComponent.path()); - isUpdated = true; - } - if (!StringUtils.equals(existingComponent.moduleUuid(), newComponent.moduleUuid())) { - existingComponent.setModuleUuid(newComponent.moduleUuid()); - isUpdated = true; - } - if (!existingComponent.moduleUuidPath().equals(newComponent.moduleUuidPath())) { - existingComponent.setModuleUuidPath(newComponent.moduleUuidPath()); - isUpdated = true; - } - if (!ObjectUtils.equals(existingComponent.parentProjectId(), newComponent.parentProjectId())) { - existingComponent.setParentProjectId(newComponent.parentProjectId()); - isUpdated = true; - } - return isUpdated; - } + private static ComponentDto createComponentDto(BatchReport.Component reportComponent, Component component) { + String componentKey = component.getKey(); + String componentUuid = component.getUuid(); - private String getFileQualifier(BatchReport.Component reportComponent) { - return reportComponent.getIsTest() ? Qualifiers.UNIT_TEST_FILE : Qualifiers.FILE; - } - - private class PersistedComponent { - private ComponentDto componentDto; - private SnapshotDto parentSnapshot; + ComponentDto componentDto = new ComponentDto(); + componentDto.setUuid(componentUuid); + componentDto.setKey(componentKey); + componentDto.setDeprecatedKey(componentKey); + componentDto.setEnabled(true); + return componentDto; + } - public PersistedComponent(ComponentDto componentDto, SnapshotDto parentSnapshot) { - this.componentDto = componentDto; - this.parentSnapshot = parentSnapshot; - } + private static boolean updateComponent(ComponentDto existingComponent, ComponentDto newComponent) { + boolean isUpdated = false; + if (!StringUtils.equals(existingComponent.name(), newComponent.name())) { + existingComponent.setName(newComponent.name()); + isUpdated = true; + } + if (!StringUtils.equals(existingComponent.description(), newComponent.description())) { + existingComponent.setDescription(newComponent.description()); + isUpdated = true; + } + if (!StringUtils.equals(existingComponent.path(), newComponent.path())) { + existingComponent.setPath(newComponent.path()); + isUpdated = true; + } + if (!StringUtils.equals(existingComponent.moduleUuid(), newComponent.moduleUuid())) { + existingComponent.setModuleUuid(newComponent.moduleUuid()); + isUpdated = true; + } + if (!existingComponent.moduleUuidPath().equals(newComponent.moduleUuidPath())) { + existingComponent.setModuleUuidPath(newComponent.moduleUuidPath()); + isUpdated = true; } + if (!ObjectUtils.equals(existingComponent.parentProjectId(), newComponent.parentProjectId())) { + existingComponent.setParentProjectId(newComponent.parentProjectId()); + isUpdated = true; + } + return isUpdated; + } + private static String getFileQualifier(BatchReport.Component reportComponent) { + return reportComponent.getIsTest() ? Qualifiers.UNIT_TEST_FILE : Qualifiers.FILE; } private static Map componentDtosByKey(List components) { @@ -339,6 +331,16 @@ public class PersistComponentsAndSnapshotsStep implements ComputationStep { }); } + private static class PersistedComponent { + private ComponentDto componentDto; + private SnapshotDto parentSnapshot; + + public PersistedComponent(ComponentDto componentDto, SnapshotDto parentSnapshot) { + this.componentDto = componentDto; + this.parentSnapshot = parentSnapshot; + } + } + @Override public String getDescription() { return "Feed components and snapshots"; diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/db/SnapshotDaoTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/db/SnapshotDaoTest.java index 48a8ff2c724..a139417951b 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/component/db/SnapshotDaoTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/component/db/SnapshotDaoTest.java @@ -142,6 +142,30 @@ public class SnapshotDaoTest extends AbstractDaoTestCase { assertThat(snapshots).extracting("id").containsOnly(1L, 6L); } + @Test + public void select_snapshots_by_component_id() { + setupData("snapshots"); + + List snapshots = sut.selectSnapshotsByComponentId(session, 1L); + + assertThat(snapshots).hasSize(3); + } + + @Test + public void insert() { + setupData("empty"); + + when(system2.now()).thenReturn(1403042400000L); + + SnapshotDto dto = defaultSnapshot(); + + sut.insert(session, dto); + session.commit(); + + assertThat(dto.getId()).isNotNull(); + checkTables("insert", "snapshots"); + } + @Test public void set_snapshot_and_children_to_false_and_status_processed() { setupData("snapshots"); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/component/DbIdsRepositoryTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/component/DbIdsRepositoryTest.java index d2c30aae8b4..c614a8bf6dc 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/component/DbIdsRepositoryTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/component/DbIdsRepositoryTest.java @@ -34,7 +34,7 @@ public class DbIdsRepositoryTest { Component component = DumbComponent.DUMB_PROJECT; @Test - public void add_and_get_component() throws Exception { + public void add_and_get_component_id() throws Exception { DbIdsRepository cache = new DbIdsRepository(); cache.setComponentId(component, 10L); @@ -42,7 +42,7 @@ public class DbIdsRepositoryTest { } @Test - public void fail_on_unknown_ref() throws Exception { + public void fail_to_get_component_id_on_unknown_ref() throws Exception { thrown.expect(IllegalArgumentException.class); thrown.expectMessage("Component ref '" + component.getRef() + "' has no component id"); @@ -59,4 +59,30 @@ public class DbIdsRepositoryTest { cache.setComponentId(component, 11L); } + @Test + public void add_and_get_snapshot_id() throws Exception { + DbIdsRepository cache = new DbIdsRepository(); + cache.setSnapshotId(component, 100L); + + assertThat(cache.getSnapshotId(component)).isEqualTo(100L); + } + + @Test + public void fail_to_get_snapshot_id_on_unknown_ref() throws Exception { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Component ref '" + component.getRef() + "' has no snapshot id"); + + new DbIdsRepository().getSnapshotId(DumbComponent.DUMB_PROJECT); + } + + @Test + public void fail_if_snapshot_id_already_set() throws Exception { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Component ref '" + component.getRef() + "' has already a snapshot id"); + + DbIdsRepository cache = new DbIdsRepository(); + cache.setSnapshotId(component, 10L); + cache.setSnapshotId(component, 11L); + } + } diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistComponentsAndSnapshotsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistComponentsAndSnapshotsStepTest.java index 2f076e3ab98..8f89c938805 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistComponentsAndSnapshotsStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistComponentsAndSnapshotsStepTest.java @@ -20,6 +20,7 @@ package org.sonar.server.computation.step; +import java.util.List; import org.junit.After; import org.junit.Before; import org.junit.ClassRule; @@ -30,10 +31,12 @@ import org.sonar.api.utils.System2; import org.sonar.batch.protocol.Constants; import org.sonar.batch.protocol.output.BatchReport; import org.sonar.core.component.ComponentDto; +import org.sonar.core.component.SnapshotDto; import org.sonar.core.persistence.DbSession; import org.sonar.core.persistence.DbTester; import org.sonar.server.component.ComponentTesting; import org.sonar.server.component.db.ComponentDao; +import org.sonar.server.component.db.SnapshotDao; import org.sonar.server.computation.batch.BatchReportReaderRule; import org.sonar.server.computation.batch.TreeRootHolderRule; import org.sonar.server.computation.component.Component; @@ -44,11 +47,14 @@ import org.sonar.test.DbTests; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; @Category(DbTests.class) public class PersistComponentsAndSnapshotsStepTest extends BaseStepTest { private static final String PROJECT_KEY = "PROJECT_KEY"; + private static final long ANALYSIS_DATE = 1000; + private static final long NOW = 2000; @ClassRule public static DbTester dbTester = new DbTester(); @@ -73,11 +79,14 @@ public class PersistComponentsAndSnapshotsStepTest extends BaseStepTest { public void setup() throws Exception { dbTester.truncateTables(); session = dbTester.myBatis().openSession(false); - dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new ComponentDao()); + dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new ComponentDao(), new SnapshotDao(system2)); + reportReader.setMetadata(BatchReport.Metadata.newBuilder() + .setAnalysisDate(ANALYSIS_DATE) + .build()); + dbIdsRepository = new DbIdsRepository(); - reportReader.setMetadata(BatchReport.Metadata.newBuilder().build()); + when(system2.now()).thenReturn(NOW); - dbIdsRepository = new DbIdsRepository(); sut = new PersistComponentsAndSnapshotsStep(system2, dbClient, treeRootHolder, reportReader, dbIdsRepository); } @@ -192,6 +201,118 @@ public class PersistComponentsAndSnapshotsStepTest extends BaseStepTest { assertThat(dbIdsRepository.getComponentId(file)).isEqualTo(fileDto.getId()); } + @Test + public void persist_snapshots() throws Exception { + reportReader.putComponent(BatchReport.Component.newBuilder() + .setRef(1) + .setType(Constants.ComponentType.PROJECT) + .setKey(PROJECT_KEY) + .setName("Project") + .setVersion("1.0") + .addChildRef(2) + .build()); + reportReader.putComponent(BatchReport.Component.newBuilder() + .setRef(2) + .setType(Constants.ComponentType.MODULE) + .setKey("MODULE_KEY") + .setPath("module") + .setName("Module") + .setVersion("1.1") + .addChildRef(3) + .build()); + reportReader.putComponent(BatchReport.Component.newBuilder() + .setRef(3) + .setType(Constants.ComponentType.DIRECTORY) + .setPath("src/main/java/dir") + .addChildRef(4) + .build()); + reportReader.putComponent(BatchReport.Component.newBuilder() + .setRef(4) + .setType(Constants.ComponentType.FILE) + .setPath("src/main/java/dir/Foo.java") + .setLanguage("java") + .build()); + + Component file = new DumbComponent(Component.Type.FILE, 4, "DEFG", "MODULE_KEY:src/main/java/dir/Foo.java"); + Component directory = new DumbComponent(Component.Type.DIRECTORY, 3, "CDEF", "MODULE_KEY:src/main/java/dir", file); + Component module = new DumbComponent(Component.Type.MODULE, 2, "BCDE", "MODULE_KEY", directory); + Component project = new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY, module); + treeRootHolder.setRoot(project); + + sut.execute(); + + assertThat(dbTester.countRowsOfTable("snapshots")).isEqualTo(4); + + ComponentDto projectDto = dbClient.componentDao().selectNullableByKey(session, PROJECT_KEY); + SnapshotDto projectSnapshot = getSnapshot(projectDto.getId()); + assertThat(projectSnapshot.getComponentId()).isEqualTo(projectDto.getId()); + assertThat(projectSnapshot.getRootProjectId()).isEqualTo(projectDto.getId()); + assertThat(projectSnapshot.getRootId()).isNull(); + assertThat(projectSnapshot.getParentId()).isNull(); + assertThat(projectSnapshot.getDepth()).isEqualTo(0); + assertThat(projectSnapshot.getPath()).isEqualTo(""); + assertThat(projectSnapshot.getQualifier()).isEqualTo("TRK"); + assertThat(projectSnapshot.getScope()).isEqualTo("PRJ"); + assertThat(projectSnapshot.getVersion()).isEqualTo("1.0"); + assertThat(projectSnapshot.getLast()).isFalse(); + assertThat(projectSnapshot.getStatus()).isEqualTo("U"); + assertThat(projectSnapshot.getCreatedAt()).isEqualTo(ANALYSIS_DATE); + assertThat(projectSnapshot.getBuildDate()).isEqualTo(NOW); + + ComponentDto moduleDto = dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY"); + SnapshotDto moduleSnapshot = getSnapshot(moduleDto.getId()); + assertThat(moduleSnapshot.getComponentId()).isEqualTo(moduleDto.getId()); + assertThat(moduleSnapshot.getRootProjectId()).isEqualTo(projectDto.getId()); + assertThat(moduleSnapshot.getRootId()).isEqualTo(projectSnapshot.getId()); + assertThat(moduleSnapshot.getParentId()).isEqualTo(projectSnapshot.getId()); + assertThat(moduleSnapshot.getDepth()).isEqualTo(1); + assertThat(moduleSnapshot.getPath()).isEqualTo(projectSnapshot.getId() + "."); + assertThat(moduleSnapshot.getQualifier()).isEqualTo("BRC"); + assertThat(moduleSnapshot.getScope()).isEqualTo("PRJ"); + assertThat(moduleSnapshot.getVersion()).isEqualTo("1.1"); + assertThat(moduleSnapshot.getLast()).isFalse(); + assertThat(moduleSnapshot.getStatus()).isEqualTo("U"); + assertThat(moduleSnapshot.getCreatedAt()).isEqualTo(ANALYSIS_DATE); + assertThat(moduleSnapshot.getBuildDate()).isEqualTo(NOW); + + ComponentDto directoryDto = dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY:src/main/java/dir"); + SnapshotDto directorySnapshot = getSnapshot(directoryDto.getId()); + assertThat(directorySnapshot.getComponentId()).isEqualTo(directoryDto.getId()); + assertThat(directorySnapshot.getRootProjectId()).isEqualTo(projectDto.getId()); + assertThat(directorySnapshot.getRootId()).isEqualTo(projectDto.getId()); + assertThat(directorySnapshot.getParentId()).isEqualTo(moduleDto.getId()); + assertThat(directorySnapshot.getDepth()).isEqualTo(2); + assertThat(directorySnapshot.getPath()).isEqualTo(projectSnapshot.getId() + "." + moduleDto.getId() + "."); + assertThat(directorySnapshot.getQualifier()).isEqualTo("DIR"); + assertThat(directorySnapshot.getScope()).isEqualTo("DIR"); + assertThat(directorySnapshot.getVersion()).isNull(); + assertThat(directorySnapshot.getLast()).isFalse(); + assertThat(directorySnapshot.getStatus()).isEqualTo("U"); + assertThat(directorySnapshot.getCreatedAt()).isEqualTo(ANALYSIS_DATE); + assertThat(directorySnapshot.getBuildDate()).isEqualTo(NOW); + + ComponentDto fileDto = dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY:src/main/java/dir/Foo.java"); + SnapshotDto fileSnapshot = getSnapshot(fileDto.getId()); + assertThat(fileSnapshot.getComponentId()).isEqualTo(fileDto.getId()); + assertThat(fileSnapshot.getRootProjectId()).isEqualTo(projectDto.getId()); + assertThat(fileSnapshot.getRootId()).isEqualTo(projectDto.getId()); + assertThat(fileSnapshot.getParentId()).isEqualTo(directoryDto.getId()); + assertThat(fileSnapshot.getDepth()).isEqualTo(3); + assertThat(fileSnapshot.getPath()).isEqualTo(projectSnapshot.getId() + "." + moduleDto.getId() + "." + directoryDto.getId() + "."); + assertThat(fileSnapshot.getQualifier()).isEqualTo("FIL"); + assertThat(fileSnapshot.getScope()).isEqualTo("FIL"); + assertThat(fileSnapshot.getVersion()).isNull(); + assertThat(fileSnapshot.getLast()).isFalse(); + assertThat(fileSnapshot.getStatus()).isEqualTo("U"); + assertThat(fileSnapshot.getCreatedAt()).isEqualTo(ANALYSIS_DATE); + assertThat(fileSnapshot.getBuildDate()).isEqualTo(NOW); + + assertThat(dbIdsRepository.getSnapshotId(project)).isEqualTo(projectSnapshot.getId()); + assertThat(dbIdsRepository.getComponentId(module)).isEqualTo(moduleDto.getId()); + assertThat(dbIdsRepository.getComponentId(directory)).isEqualTo(directoryDto.getId()); + assertThat(dbIdsRepository.getComponentId(file)).isEqualTo(fileDto.getId()); + } + @Test public void persist_file_directly_attached_on_root_directory() throws Exception { reportReader.putComponent(BatchReport.Component.newBuilder() @@ -480,6 +601,78 @@ public class PersistComponentsAndSnapshotsStepTest extends BaseStepTest { assertThat(moduleB.parentProjectId()).isEqualTo(project.getId()); } + @Test + public void persist_snapshots_on_multi_modules() throws Exception { + reportReader.putComponent(BatchReport.Component.newBuilder() + .setRef(1) + .setType(Constants.ComponentType.PROJECT) + .setKey(PROJECT_KEY) + .setName("Project") + .addChildRef(2) + .addChildRef(4) + .build()); + reportReader.putComponent(BatchReport.Component.newBuilder() + .setRef(2) + .setType(Constants.ComponentType.MODULE) + .setKey("MODULE_A") + .setName("Module A") + .addChildRef(3) + .build()); + reportReader.putComponent(BatchReport.Component.newBuilder() + .setRef(3) + .setType(Constants.ComponentType.MODULE) + .setKey("SUB_MODULE_A") + .setName("Sub Module A") + .build()); + reportReader.putComponent(BatchReport.Component.newBuilder() + .setRef(4) + .setType(Constants.ComponentType.MODULE) + .setKey("MODULE_B") + .setName("Module B") + .build()); + + treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY, + new DumbComponent(Component.Type.MODULE, 2, "BCDE", "MODULE_A", + new DumbComponent(Component.Type.MODULE, 3, "DEFG", "SUB_MODULE_A")), + new DumbComponent(Component.Type.MODULE, 4, "CDEF", "MODULE_B"))); + + sut.execute(); + + assertThat(dbTester.countRowsOfTable("snapshots")).isEqualTo(4); + + ComponentDto project = dbClient.componentDao().selectNullableByKey(session, PROJECT_KEY); + SnapshotDto projectSnapshot = getSnapshot(project.getId()); + assertThat(projectSnapshot.getRootProjectId()).isEqualTo(project.getId()); + assertThat(projectSnapshot.getRootId()).isNull(); + assertThat(projectSnapshot.getParentId()).isNull(); + assertThat(projectSnapshot.getDepth()).isEqualTo(0); + assertThat(projectSnapshot.getPath()).isEqualTo(""); + + ComponentDto moduleA = dbClient.componentDao().selectNullableByKey(session, "MODULE_A"); + SnapshotDto moduleASnapshot = getSnapshot(moduleA.getId()); + assertThat(moduleASnapshot.getRootProjectId()).isEqualTo(project.getId()); + assertThat(moduleASnapshot.getRootId()).isEqualTo(projectSnapshot.getId()); + assertThat(moduleASnapshot.getParentId()).isEqualTo(projectSnapshot.getId()); + assertThat(moduleASnapshot.getDepth()).isEqualTo(1); + assertThat(moduleASnapshot.getPath()).isEqualTo(projectSnapshot.getId() + "."); + + ComponentDto subModuleA = dbClient.componentDao().selectNullableByKey(session, "SUB_MODULE_A"); + SnapshotDto subModuleASnapshot = getSnapshot(subModuleA.getId()); + assertThat(subModuleASnapshot.getRootProjectId()).isEqualTo(project.getId()); + assertThat(subModuleASnapshot.getRootId()).isEqualTo(project.getId()); + assertThat(subModuleASnapshot.getParentId()).isEqualTo(moduleA.getId()); + assertThat(subModuleASnapshot.getDepth()).isEqualTo(2); + assertThat(subModuleASnapshot.getPath()).isEqualTo(projectSnapshot.getId() + "." + moduleA.getId() + "."); + + ComponentDto moduleB = dbClient.componentDao().selectNullableByKey(session, "MODULE_B"); + SnapshotDto moduleBSnapshot = getSnapshot(moduleB.getId()); + assertThat(moduleBSnapshot.getRootProjectId()).isEqualTo(project.getId()); + assertThat(moduleBSnapshot.getRootId()).isEqualTo(project.getId()); + assertThat(moduleBSnapshot.getParentId()).isEqualTo(project.getId()); + assertThat(moduleBSnapshot.getDepth()).isEqualTo(1); + assertThat(moduleBSnapshot.getPath()).isEqualTo(projectSnapshot.getId() + "." ); + } + @Test public void nothing_to_persist() throws Exception { ComponentDto project = ComponentTesting.newProjectDto("ABCD").setKey(PROJECT_KEY).setName("Project"); @@ -764,4 +957,10 @@ public class PersistComponentsAndSnapshotsStepTest extends BaseStepTest { assertThat(fileReloaded.parentProjectId()).isEqualTo(moduleBReloaded.getId()); } + private SnapshotDto getSnapshot(long componentId){ + List projectSnapshots = dbClient.snapshotDao().selectSnapshotsByComponentId(session, componentId); + assertThat(projectSnapshots).hasSize(1); + return projectSnapshots.get(0); + } + } diff --git a/sonar-core/src/main/java/org/sonar/core/component/db/SnapshotMapper.java b/sonar-core/src/main/java/org/sonar/core/component/db/SnapshotMapper.java index bb650d5622d..806128b0d9d 100644 --- a/sonar-core/src/main/java/org/sonar/core/component/db/SnapshotMapper.java +++ b/sonar-core/src/main/java/org/sonar/core/component/db/SnapshotMapper.java @@ -35,6 +35,8 @@ public interface SnapshotMapper { @CheckForNull SnapshotDto selectLastSnapshot(Long resourceId); + List selectSnapshotsByComponentId(Long resourceId); + List selectSnapshotAndChildrenOfScope(@Param(value = "snapshot") Long resourceId, @Param(value = "scope") String scope); int updateSnapshotAndChildrenLastFlagAndStatus(@Param(value = "root") Long rootId, @Param(value = "pathRootId") Long pathRootId, diff --git a/sonar-core/src/main/resources/org/sonar/core/component/db/SnapshotMapper.xml b/sonar-core/src/main/resources/org/sonar/core/component/db/SnapshotMapper.xml index 4beb1ceec52..fb9c6b44062 100644 --- a/sonar-core/src/main/resources/org/sonar/core/component/db/SnapshotMapper.xml +++ b/sonar-core/src/main/resources/org/sonar/core/component/db/SnapshotMapper.xml @@ -51,6 +51,13 @@ where s.islast=${_true} and s.project_id = #{resource} + +