diff options
17 files changed, 241 insertions, 51 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectRepositoryLoader.java b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectRepositoryLoader.java index 08212e713c5..d3b5a31998c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectRepositoryLoader.java +++ b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectRepositoryLoader.java @@ -26,9 +26,11 @@ import com.google.common.collect.Multimap; import org.sonar.api.ServerComponent; import org.sonar.api.resources.Language; import org.sonar.api.resources.Languages; +import org.sonar.batch.protocol.input.FileData; import org.sonar.batch.protocol.input.ProjectReferentials; import org.sonar.core.UtcDateUtils; import org.sonar.core.component.ComponentDto; +import org.sonar.core.component.FilePathWithHashDto; import org.sonar.core.permission.GlobalPermissions; import org.sonar.core.persistence.DbSession; import org.sonar.core.persistence.MyBatis; @@ -89,15 +91,20 @@ public class ProjectRepositoryLoader implements ServerComponent { projectKey = project.key(); } - List<PropertyDto> moduleSettings = dbClient.propertiesDao().selectProjectProperties(query.getModuleKey(), session); List<ComponentDto> moduleChildren = dbClient.componentDao().findChildrenModulesFromModule(session, query.getModuleKey()); + moduleChildren.add(module); + Map<String, String> moduleUuidsByKey = moduleUuidsByKey(module, moduleChildren); + Map<String, Long> moduleIdsByKey = moduleIdsByKey(module, moduleChildren); + + List<PropertyDto> moduleSettings = dbClient.propertiesDao().selectProjectProperties(query.getModuleKey(), session); List<PropertyDto> moduleChildrenSettings = newArrayList(); if (!moduleChildren.isEmpty()) { moduleChildrenSettings = dbClient.propertiesDao().findChildrenModuleProperties(query.getModuleKey(), session); } - TreeModuleSettings treeModuleSettings = new TreeModuleSettings(moduleChildren, moduleChildrenSettings, module, moduleSettings); + TreeModuleSettings treeModuleSettings = new TreeModuleSettings(moduleUuidsByKey, moduleIdsByKey, moduleChildren, moduleChildrenSettings, module, moduleSettings); addSettingsToChildrenModules(ref, query.getModuleKey(), Maps.<String, String>newHashMap(), treeModuleSettings, hasScanPerm, session); + addFileData(session, ref, moduleChildren, module.key()); } else { // Add settings of the provisioned project addSettings(ref, query.getModuleKey(), getPropertiesMap(dbClient.propertiesDao().selectProjectProperties(query.getModuleKey(), session), hasScanPerm)); @@ -218,6 +225,18 @@ public class ProjectRepositoryLoader implements ServerComponent { } } + private void addFileData(DbSession session, ProjectReferentials ref, List<ComponentDto> moduleChildren, String moduleKey) { + Map<String, String> moduleKeysByUuid = newHashMap(); + for (ComponentDto module : moduleChildren) { + moduleKeysByUuid.put(module.uuid(), module.key()); + } + + for (FilePathWithHashDto file : dbClient.componentDao().findFilesFromModule(session, moduleKey)) { + FileData fileData = new FileData(file.getSrcHash(), false, null, null, null); + ref.addFileData(moduleKeysByUuid.get(file.getModuleUuid()), file.getPath(), fileData); + } + } + private void checkPermission(boolean preview) { UserSession userSession = UserSession.get(); boolean hasScanPerm = userSession.hasGlobalPermission(GlobalPermissions.SCAN_EXECUTION); @@ -231,6 +250,22 @@ public class ProjectRepositoryLoader implements ServerComponent { } } + private Map<String, String> moduleUuidsByKey(ComponentDto module, List<ComponentDto> moduleChildren) { + Map<String, String> moduleUuidsByKey = newHashMap(); + for (ComponentDto componentDto : moduleChildren) { + moduleUuidsByKey.put(componentDto.key(), componentDto.uuid()); + } + return moduleUuidsByKey; + } + + private Map<String, Long> moduleIdsByKey(ComponentDto module, List<ComponentDto> moduleChildren) { + Map<String, Long> moduleIdsByKey = newHashMap(); + for (ComponentDto componentDto : moduleChildren) { + moduleIdsByKey.put(componentDto.key(), componentDto.getId()); + } + return moduleIdsByKey; + } + private static class TreeModuleSettings { private Map<String, Long> moduleIdsByKey; @@ -238,10 +273,11 @@ public class ProjectRepositoryLoader implements ServerComponent { private Multimap<Long, PropertyDto> propertiesByModuleId; private Multimap<String, ComponentDto> moduleChildrenByModuleUuid; - private TreeModuleSettings(List<ComponentDto> moduleChildren, List<PropertyDto> moduleChildrenSettings, ComponentDto module, List<PropertyDto> moduleSettings) { + private TreeModuleSettings(Map<String, String> moduleUuidsByKey, Map<String, Long> moduleIdsByKey, List<ComponentDto> moduleChildren, + List<PropertyDto> moduleChildrenSettings, ComponentDto module, List<PropertyDto> moduleSettings) { + this.moduleIdsByKey = moduleIdsByKey; + this.moduleUuidsByKey = moduleUuidsByKey; propertiesByModuleId = ArrayListMultimap.create(); - moduleIdsByKey = newHashMap(); - moduleUuidsByKey = newHashMap(); moduleChildrenByModuleUuid = ArrayListMultimap.create(); for (PropertyDto settings : moduleChildrenSettings) { @@ -249,26 +285,20 @@ public class ProjectRepositoryLoader implements ServerComponent { } propertiesByModuleId.putAll(module.getId(), moduleSettings); - moduleIdsByKey.put(module.key(), module.getId()); - moduleUuidsByKey.put(module.key(), module.uuid()); for (ComponentDto componentDto : moduleChildren) { - moduleIdsByKey.put(componentDto.key(), componentDto.getId()); - moduleUuidsByKey.put(componentDto.key(), componentDto.uuid()); String moduleUuid = componentDto.moduleUuid(); if (moduleUuid != null) { moduleChildrenByModuleUuid.put(moduleUuid, componentDto); - } else { - moduleChildrenByModuleUuid.put(module.uuid(), componentDto); } } } - private List<PropertyDto> findModuleSettings(String moduleKey) { + List<PropertyDto> findModuleSettings(String moduleKey) { Long moduleId = moduleIdsByKey.get(moduleKey); return newArrayList(propertiesByModuleId.get(moduleId)); } - private List<ComponentDto> findChildrenModule(String moduleKey) { + List<ComponentDto> findChildrenModule(String moduleKey) { String moduleUuid = moduleUuidsByKey.get(moduleKey); return newArrayList(moduleChildrenByModuleUuid.get(moduleUuid)); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/db/ComponentDao.java b/server/sonar-server/src/main/java/org/sonar/server/component/db/ComponentDao.java index df4ef97c70d..b96b81fdb8b 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/component/db/ComponentDao.java +++ b/server/sonar-server/src/main/java/org/sonar/server/component/db/ComponentDao.java @@ -22,8 +22,10 @@ package org.sonar.server.component.db; import com.google.common.collect.Lists; import org.sonar.api.ServerComponent; +import org.sonar.api.resources.Scopes; import org.sonar.api.utils.System2; import org.sonar.core.component.ComponentDto; +import org.sonar.core.component.FilePathWithHashDto; import org.sonar.core.component.db.ComponentMapper; import org.sonar.core.persistence.DaoComponent; import org.sonar.core.persistence.DbSession; @@ -115,7 +117,11 @@ public class ComponentDao extends BaseDao<ComponentMapper, ComponentDto, String> } public List<ComponentDto> findChildrenModulesFromModule(DbSession session, String moduleKey) { - return mapper(session).findChildrenModulesFromModule(moduleKey); + return mapper(session).findChildrenModulesFromModule(moduleKey, Scopes.PROJECT); + } + + public List<FilePathWithHashDto> findFilesFromModule(DbSession session, String moduleKey) { + return mapper(session).findFilesFromModule(moduleKey, Scopes.FILE); } public List<ComponentDto> getByUuids(DbSession session, Collection<String> uuids) { 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 213467f8903..f0afc447e26 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 @@ -70,7 +70,7 @@ public class SnapshotDao extends BaseDao<SnapshotMapper, SnapshotDto, Long> impl * Return all snapshots children (not returning itself) from a module key */ public List<SnapshotDto> findChildrenModulesFromModule(DbSession session, String moduleKey) { - return mapper(session).selectChildrenModulesFromModule(moduleKey); + return mapper(session).selectChildrenModulesFromModule(moduleKey, Scopes.PROJECT); } public int updateSnapshotAndChildrenLastFlagAndStatus(DbSession session, SnapshotDto snapshot, boolean isLast, String status) { diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectRepositoryLoaderMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectRepositoryLoaderMediumTest.java index 6c875a3a5df..152e5028237 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectRepositoryLoaderMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectRepositoryLoaderMediumTest.java @@ -30,6 +30,7 @@ import org.sonar.api.rule.Severity; import org.sonar.api.server.rule.RuleParamType; import org.sonar.api.utils.DateUtils; import org.sonar.batch.protocol.input.ActiveRule; +import org.sonar.batch.protocol.input.FileData; import org.sonar.batch.protocol.input.ProjectReferentials; import org.sonar.batch.protocol.input.QProfile; import org.sonar.core.component.ComponentDto; @@ -40,6 +41,8 @@ import org.sonar.core.properties.PropertyDto; import org.sonar.core.qualityprofile.db.QualityProfileDto; import org.sonar.core.rule.RuleDto; import org.sonar.core.rule.RuleParamDto; +import org.sonar.core.source.db.FileSourceDao; +import org.sonar.core.source.db.FileSourceDto; import org.sonar.server.component.ComponentTesting; import org.sonar.server.component.SnapshotTesting; import org.sonar.server.db.DbClient; @@ -698,6 +701,38 @@ public class ProjectRepositoryLoaderMediumTest { } } + @Test + public void add_file_data() throws Exception { + MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION); + + ComponentDto project = ComponentTesting.newProjectDto(); + tester.get(DbClient.class).componentDao().insert(dbSession, project); + SnapshotDto projectSnapshot = SnapshotTesting.createForProject(project); + tester.get(DbClient.class).snapshotDao().insert(dbSession, projectSnapshot); + addDefaultProfile(); + + ComponentDto file = ComponentTesting.newFileDto(project, "file"); + tester.get(DbClient.class).componentDao().insert(dbSession, file); + tester.get(DbClient.class).snapshotDao().insert(dbSession, SnapshotTesting.createForComponent(file, projectSnapshot)); + tester.get(FileSourceDao.class).insert(new FileSourceDto() + .setFileUuid(file.uuid()) + .setProjectUuid(project.uuid()) + .setData(",,,,,,,,,,,,,,,unchanged ,,,,,,,,,,,,,,,content ") + .setDataHash("0263047cd758c68c27683625f072f010") + .setLineHashes("8d7b3d6b83c0a517eac07e1aac94b773") + .setCreatedAt(new Date().getTime()) + .setUpdatedAt(new Date().getTime()) + .setSrcHash("123456") + ); + + dbSession.commit(); + + ProjectReferentials ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key())); + assertThat(ref.fileDataByPath(project.key())).hasSize(1); + FileData fileData = ref.fileData(project.key(), file.path()); + assertThat(fileData.hash()).isEqualTo("123456"); + } + private void addDefaultProfile() { QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt( DateUtils.formatDateTime(new Date())); diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/db/ComponentDaoTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/db/ComponentDaoTest.java index ac8fafe3fe1..aa300d52e2d 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/component/db/ComponentDaoTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/component/db/ComponentDaoTest.java @@ -27,6 +27,7 @@ import org.junit.Test; import org.sonar.api.utils.DateUtils; import org.sonar.api.utils.System2; import org.sonar.core.component.ComponentDto; +import org.sonar.core.component.FilePathWithHashDto; import org.sonar.core.persistence.AbstractDaoTestCase; import org.sonar.core.persistence.DbSession; import org.sonar.server.exceptions.NotFoundException; @@ -336,11 +337,11 @@ public class ComponentDaoTest extends AbstractDaoTestCase { // From root project List<ComponentDto> modules = dao.findChildrenModulesFromModule(session, "org.struts:struts"); - assertThat(modules).extracting("id").containsOnly(2L, 3L); + assertThat(modules).extracting("uuid").containsOnly("EFGH", "FGHI"); // From module modules = dao.findChildrenModulesFromModule(session, "org.struts:struts-core"); - assertThat(modules).extracting("id").containsOnly(3L); + assertThat(modules).extracting("uuid").containsOnly("FGHI"); // From sub module modules = dao.findChildrenModulesFromModule(session, "org.struts:struts-data"); @@ -348,6 +349,35 @@ public class ComponentDaoTest extends AbstractDaoTestCase { } @Test + public void findFilesFromModule() throws Exception { + setupData("multi-modules", "files_hashes"); + + // From root project + List<FilePathWithHashDto> files = dao.findFilesFromModule(session, "org.struts:struts"); + assertThat(files).extracting("uuid").containsOnly("HIJK"); + assertThat(files).extracting("moduleUuid").containsOnly("FGHI"); + assertThat(files).extracting("srcHash").containsOnly("123456"); + assertThat(files).extracting("path").containsOnly("src/org/struts/RequestContext.java"); + + // From module + files = dao.findFilesFromModule(session, "org.struts:struts-core"); + assertThat(files).extracting("uuid").containsOnly("HIJK"); + assertThat(files).extracting("moduleUuid").containsOnly("FGHI"); + assertThat(files).extracting("srcHash").containsOnly("123456"); + assertThat(files).extracting("path").containsOnly("src/org/struts/RequestContext.java"); + + // From sub module + files = dao.findFilesFromModule(session, "org.struts:struts-data"); + assertThat(files).extracting("uuid").containsOnly("HIJK"); + assertThat(files).extracting("moduleUuid").containsOnly("FGHI"); + assertThat(files).extracting("srcHash").containsOnly("123456"); + assertThat(files).extracting("path").containsOnly("src/org/struts/RequestContext.java"); + + // From unknown + assertThat(dao.findFilesFromModule(session, "unknown")).isEmpty(); + } + + @Test public void insert() { when(system2.now()).thenReturn(DateUtils.parseDate("2014-06-18").getTime()); setupData("empty"); diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/db/ComponentDaoTest/files_hashes.xml b/server/sonar-server/src/test/resources/org/sonar/server/component/db/ComponentDaoTest/files_hashes.xml new file mode 100644 index 00000000000..5766f85fe8a --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/component/db/ComponentDaoTest/files_hashes.xml @@ -0,0 +1,10 @@ +<dataset> + + <file_sources id="101" project_uuid="ABCD" file_uuid="HIJK" + data=",,,,,,,,,,,,,,,unchanged ,,,,,,,,,,,,,,,content " + line_hashes="8d7b3d6b83c0a517eac07e1aac94b773 9a0364b9e99bb480dd25e1f0284c8555" + data_hash="0263047cd758c68c27683625f072f010" + src_hash="123456" + created_at="1412952242000" updated_at="1412952242000"/> + +</dataset> diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/db/ComponentDaoTest/multi-modules.xml b/server/sonar-server/src/test/resources/org/sonar/server/component/db/ComponentDaoTest/multi-modules.xml index 49ff0123e76..dbcb59acd3a 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/component/db/ComponentDaoTest/multi-modules.xml +++ b/server/sonar-server/src/test/resources/org/sonar/server/component/db/ComponentDaoTest/multi-modules.xml @@ -30,7 +30,7 @@ <!-- module --> <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core" - uuid="EFGH" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="ABCD." + uuid="EFGH" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="ABCD" scope="PRJ" qualifier="BRC" long_name="Struts Core" description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" authorization_updated_at="[null]" /> <snapshots id="2" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1" @@ -45,7 +45,7 @@ <!-- sub module --> <projects id="3" root_id="1" kee="org.struts:struts-data" name="Struts Data" - uuid="FGHI" project_uuid="ABCD" module_uuid="EFGH" module_uuid_path="ABCD.EFGH." + uuid="FGHI" project_uuid="ABCD" module_uuid="EFGH" module_uuid_path="ABCD.EFGH" scope="PRJ" qualifier="BRC" long_name="Struts Data" description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" authorization_updated_at="[null]" /> <snapshots id="3" project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1" @@ -60,7 +60,7 @@ <!-- directory --> <projects long_name="org.struts" id="4" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts" - uuid="GHIJ" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path="ABCD.EFGH.FGHI." + uuid="GHIJ" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path="ABCD.EFGH.FGHI" name="src/org/struts" root_id="3" description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/org/struts" authorization_updated_at="[null]" /> @@ -76,7 +76,7 @@ <!-- file --> <projects long_name="org.struts.RequestContext" id="5" scope="FIL" qualifier="FIL" kee="org.struts:struts-core:src/org/struts/RequestContext.java" - uuid="HIJK" project_uuid="ABCD" module_uuid="GHIJ" module_uuid_path="ABCD.EFGH.FGHI.GHIJ." + uuid="HIJK" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path="ABCD.EFGH.FGHI" name="RequestContext.java" root_id="3" description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="src/org/struts/RequestContext.java" authorization_updated_at="[null]" /> diff --git a/server/sonar-server/src/test/resources/org/sonar/server/component/db/SnapshotDaoTest/modules.xml b/server/sonar-server/src/test/resources/org/sonar/server/component/db/SnapshotDaoTest/modules.xml index 8bc9decea38..d5c533536a9 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/component/db/SnapshotDaoTest/modules.xml +++ b/server/sonar-server/src/test/resources/org/sonar/server/component/db/SnapshotDaoTest/modules.xml @@ -26,7 +26,7 @@ <!-- module --> <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core" - uuid="EFGH" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="ABCD." + uuid="EFGH" project_uuid="ABCD" module_uuid="[null]" module_uuid_path="ABCD" scope="PRJ" qualifier="BRC" long_name="Struts Core" description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" authorization_updated_at="[null]" /> <snapshots id="2" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1" @@ -41,7 +41,7 @@ <!-- sub module --> <projects id="3" root_id="1" kee="org.struts:struts-data" name="Struts Data" - uuid="FGHI" project_uuid="ABCD" module_uuid="EFGH" module_uuid_path="ABCD.EFGH." + uuid="FGHI" project_uuid="ABCD" module_uuid="EFGH" module_uuid_path="ABCD.EFGH" scope="PRJ" qualifier="BRC" long_name="Struts Data" description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" authorization_updated_at="[null]" /> <snapshots id="3" project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1" @@ -56,7 +56,7 @@ <!-- directory --> <projects long_name="org.struts" id="4" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts" - uuid="GHIJ" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path="ABCD.EFGH.FGHI." + uuid="GHIJ" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path="ABCD.EFGH.FGHI" name="src/org/struts" root_id="3" description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/org/struts" authorization_updated_at="[null]" /> @@ -72,7 +72,7 @@ <!-- file --> <projects long_name="org.struts.RequestContext" id="5" scope="FIL" qualifier="FIL" kee="org.struts:struts-core:src/org/struts/RequestContext.java" - uuid="HIJK" project_uuid="ABCD" module_uuid="GHIJ" module_uuid_path="ABCD.EFGH.FGHI.GHIJ." + uuid="HIJK" project_uuid="ABCD" module_uuid="FGHI" module_uuid_path="ABCD.EFGH.FGHI" name="RequestContext.java" root_id="3" description="[null]" enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="src/org/struts/RequestContext.java" authorization_updated_at="[null]" /> diff --git a/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/ProjectReferentials.java b/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/ProjectReferentials.java index b945da6f7b8..8e83d0fabf5 100644 --- a/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/ProjectReferentials.java +++ b/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/ProjectReferentials.java @@ -24,12 +24,7 @@ import org.sonar.batch.protocol.GsonHelper; import javax.annotation.CheckForNull; import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; +import java.util.*; /** * Container for all project data going from server to batch. @@ -44,15 +39,15 @@ public class ProjectReferentials { private Map<String, Map<String, FileData>> fileDataByModuleAndPath = new HashMap<String, Map<String, FileData>>(); private Date lastAnalysisDate; - public Map<String, String> settings(String projectKey) { - return settingsByModule.containsKey(projectKey) ? settingsByModule.get(projectKey) : Collections.<String, String>emptyMap(); + public Map<String, String> settings(String moduleKey) { + return settingsByModule.containsKey(moduleKey) ? settingsByModule.get(moduleKey) : Collections.<String, String>emptyMap(); } - public ProjectReferentials addSettings(String projectKey, Map<String, String> settings) { - Map<String, String> existingSettings = settingsByModule.get(projectKey); + public ProjectReferentials addSettings(String moduleKey, Map<String, String> settings) { + Map<String, String> existingSettings = settingsByModule.get(moduleKey); if (existingSettings == null) { - existingSettings = new HashMap<String, String>(); - settingsByModule.put(projectKey, existingSettings); + existingSettings = new HashMap<>(); + settingsByModule.put(moduleKey, existingSettings); } existingSettings.putAll(settings); return this; @@ -76,15 +71,15 @@ public class ProjectReferentials { return this; } - public Map<String, FileData> fileDataByPath(String projectKey) { - return fileDataByModuleAndPath.containsKey(projectKey) ? fileDataByModuleAndPath.get(projectKey) : Collections.<String, FileData>emptyMap(); + public Map<String, FileData> fileDataByPath(String moduleKey) { + return fileDataByModuleAndPath.containsKey(moduleKey) ? fileDataByModuleAndPath.get(moduleKey) : Collections.<String, FileData>emptyMap(); } - public ProjectReferentials addFileData(String projectKey, String path, FileData fileData) { - Map<String, FileData> existingFileDataByPath = fileDataByModuleAndPath.get(projectKey); + public ProjectReferentials addFileData(String moduleKey, String path, FileData fileData) { + Map<String, FileData> existingFileDataByPath = fileDataByModuleAndPath.get(moduleKey); if (existingFileDataByPath == null) { - existingFileDataByPath = new HashMap<String, FileData>(); - fileDataByModuleAndPath.put(projectKey, existingFileDataByPath); + existingFileDataByPath = new HashMap<>(); + fileDataByModuleAndPath.put(moduleKey, existingFileDataByPath); } existingFileDataByPath.put(path, fileData); return this; diff --git a/sonar-core/src/main/java/org/sonar/core/component/FilePathWithHashDto.java b/sonar-core/src/main/java/org/sonar/core/component/FilePathWithHashDto.java new file mode 100644 index 00000000000..0cc55dc1607 --- /dev/null +++ b/sonar-core/src/main/java/org/sonar/core/component/FilePathWithHashDto.java @@ -0,0 +1,61 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.core.component; + +public class FilePathWithHashDto { + + private String uuid; + private String moduleUuid; + private String path; + private String srcHash; + + public String getSrcHash() { + return srcHash; + } + + public void setSrcHash(String srcHash) { + this.srcHash = srcHash; + } + + public String getModuleUuid() { + return moduleUuid; + } + + public void setModuleUuid(String moduleUuid) { + this.moduleUuid = moduleUuid; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } +} diff --git a/sonar-core/src/main/java/org/sonar/core/component/db/ComponentMapper.java b/sonar-core/src/main/java/org/sonar/core/component/db/ComponentMapper.java index b37a53f6b52..2e6d8c97265 100644 --- a/sonar-core/src/main/java/org/sonar/core/component/db/ComponentMapper.java +++ b/sonar-core/src/main/java/org/sonar/core/component/db/ComponentMapper.java @@ -22,6 +22,7 @@ package org.sonar.core.component.db; import org.apache.ibatis.annotations.Param; import org.sonar.core.component.ComponentDto; +import org.sonar.core.component.FilePathWithHashDto; import javax.annotation.CheckForNull; @@ -73,6 +74,7 @@ public interface ComponentMapper { * Warning, projectId are always null */ List<ComponentDto> findByUuids(@Param("uuids") Collection<String> uuids); + /** * Return all project (PRJ/TRK) uuids */ @@ -81,7 +83,12 @@ public interface ComponentMapper { /** * Return all modules children (not returning itself) from a module key */ - List<ComponentDto> findChildrenModulesFromModule(@Param("moduleKey") String moduleKey); + List<ComponentDto> findChildrenModulesFromModule(@Param("moduleKey") String moduleKey, @Param(value = "scope") String scope); + + /** + * Return all files children from a module key + */ + List<FilePathWithHashDto> findFilesFromModule(@Param("moduleKey") String moduleKey, @Param(value = "scope") String scope); long countById(long id); 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 31f1167a686..e47960c5855 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 @@ -43,11 +43,11 @@ public interface SnapshotMapper { List<SnapshotDto> selectSnapshotAndChildrenOfScope(@Param(value = "snapshot") Long resourceId, @Param(value = "scope") String scope); - List<SnapshotDto> selectChildrenModulesFromModule(@Param(value = "moduleKey") String moduleKey); + List<SnapshotDto> selectChildrenModulesFromModule(@Param(value = "moduleKey") String moduleKey, @Param(value = "scope") String scope); int updateSnapshotAndChildrenLastFlagAndStatus(@Param(value = "root") Long rootId, @Param(value = "pathRootId") Long pathRootId, @Param(value = "path") String path, @Param(value = "isLast") boolean isLast, @Param(value = "status") String status); int updateSnapshotAndChildrenLastFlag(@Param(value = "root") Long rootId, @Param(value = "pathRootId") Long pathRootId, - @Param(value = "path") String path, @Param(value = "isLast") boolean isLast); + @Param(value = "path") String path, @Param(value = "isLast") boolean isLast); } diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java b/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java index a72523a6e9d..922ac8e7be2 100644 --- a/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java +++ b/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java @@ -36,6 +36,7 @@ import org.sonar.core.activity.db.ActivityDto; import org.sonar.core.activity.db.ActivityMapper; import org.sonar.core.cluster.WorkQueue; import org.sonar.core.component.ComponentDto; +import org.sonar.core.component.FilePathWithHashDto; import org.sonar.core.component.SnapshotDto; import org.sonar.core.component.db.ComponentMapper; import org.sonar.core.component.db.SnapshotMapper; @@ -181,6 +182,7 @@ public class MyBatis implements BatchComponent, ServerComponent { loadAlias(conf, "Activity", ActivityDto.class); loadAlias(conf, "AnalysisReport", AnalysisReportDto.class); loadAlias(conf, "IdUuidPair", IdUuidPair.class); + loadAlias(conf, "FilePathWithHash", FilePathWithHashDto.class); // AuthorizationMapper has to be loaded before IssueMapper because this last one used it loadMapper(conf, "org.sonar.core.user.AuthorizationMapper"); diff --git a/sonar-core/src/main/java/org/sonar/core/properties/PropertiesDao.java b/sonar-core/src/main/java/org/sonar/core/properties/PropertiesDao.java index 4fa7f90797e..ef8d7c3e052 100644 --- a/sonar-core/src/main/java/org/sonar/core/properties/PropertiesDao.java +++ b/sonar-core/src/main/java/org/sonar/core/properties/PropertiesDao.java @@ -26,6 +26,7 @@ import org.apache.commons.lang.StringUtils; import org.apache.ibatis.session.SqlSession; import org.sonar.api.BatchComponent; import org.sonar.api.ServerComponent; +import org.sonar.api.resources.Scopes; import org.sonar.core.persistence.DaoComponent; import org.sonar.core.persistence.DbSession; import org.sonar.core.persistence.MyBatis; @@ -123,7 +124,7 @@ public class PropertiesDao implements BatchComponent, ServerComponent, DaoCompon } public List<PropertyDto> findChildrenModuleProperties(String moduleKey, SqlSession session) { - return session.getMapper(PropertiesMapper.class).selectChildrenModuleProperties(moduleKey); + return session.getMapper(PropertiesMapper.class).selectChildrenModuleProperties(moduleKey, Scopes.PROJECT); } public PropertyDto selectProjectProperty(long resourceId, String propertyKey) { diff --git a/sonar-core/src/main/java/org/sonar/core/properties/PropertiesMapper.java b/sonar-core/src/main/java/org/sonar/core/properties/PropertiesMapper.java index 3fc4311c509..7b38027b823 100644 --- a/sonar-core/src/main/java/org/sonar/core/properties/PropertiesMapper.java +++ b/sonar-core/src/main/java/org/sonar/core/properties/PropertiesMapper.java @@ -44,7 +44,7 @@ public interface PropertiesMapper { List<PropertyDto> selectByQuery(@Param("query") PropertyQuery query); - List<PropertyDto> selectChildrenModuleProperties(@Param("moduleKey") String moduleKey); + List<PropertyDto> selectChildrenModuleProperties(@Param("moduleKey") String moduleKey, @Param(value = "scope") String scope); void update(PropertyDto property); diff --git a/sonar-core/src/main/resources/org/sonar/core/component/db/ComponentMapper.xml b/sonar-core/src/main/resources/org/sonar/core/component/db/ComponentMapper.xml index 2fe0703ec10..ce4f09ea483 100644 --- a/sonar-core/src/main/resources/org/sonar/core/component/db/ComponentMapper.xml +++ b/sonar-core/src/main/resources/org/sonar/core/component/db/ComponentMapper.xml @@ -132,10 +132,23 @@ </where> </select> - <select id="findChildrenModulesFromModule" parameterType="String" resultType="Component"> + <select id="findChildrenModulesFromModule" parameterType="map" resultType="Component"> SELECT <include refid="componentColumns"/> FROM projects p - INNER JOIN (<include refid="org.sonar.core.component.db.SnapshotMapper.selectChildrenModulesFromModuleQuery" />) snapshotModules on snapshotModules.resourceId=p.id + INNER JOIN (<include refid="org.sonar.core.component.db.SnapshotMapper.selectChildrenModulesFromModuleQuery"/>) snapshotModules ON snapshotModules.resourceId=p.id + <where> + AND p.enabled=${_true} + </where> + </select> + + <select id="findFilesFromModule" parameterType="map" resultType="FilePathWithHash"> + SELECT p.uuid, p.path, p.module_uuid as moduleUuid, fs.src_hash as srcHash + FROM projects p + INNER JOIN (<include refid="org.sonar.core.component.db.SnapshotMapper.selectChildrenModulesFromModuleQuery"/>) snapshotModules ON snapshotModules.resourceId=p.id + INNER JOIN file_sources fs ON fs.file_uuid=p.uuid + <where> + AND p.enabled=${_true} + </where> </select> <select id="findProjectUuids" resultType="String"> 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 0aeb697a2c3..e205fd9e4d3 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 @@ -80,7 +80,7 @@ INNER JOIN projects module ON module.id = current_snapshot.project_id AND module.enabled = ${_true} AND module.kee = #{moduleKey} <where> AND s.islast = ${_true} - AND s.scope = 'PRJ' + AND s.scope = #{scope} AND <choose> <when test="_databaseId == 'mssql'"> s.path LIKE current_snapshot.path + CAST(current_snapshot.id AS varchar(15)) + '.%' |