From 2bc5c0c7689068f5403d474901d264458afa036a Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Lievremont Date: Mon, 23 Mar 2015 18:18:18 +0100 Subject: [PATCH] SONAR-6329 Update handling of project/profile association in service layer and DAOs --- .../qualityprofile/QProfileFactory.java | 26 ++++----- .../qualityprofile/QProfileProjectLookup.java | 9 +-- .../QProfileProjectOperations.java | 15 ++--- .../RegisterQualityProfiles.java | 19 ++----- .../ProjectRepositoryLoaderMediumTest.java | 27 ++++----- .../QProfileFactoryMediumTest.java | 27 ++------- .../QProfileProjectOperationsMediumTest.java | 4 ++ .../RegisterQualityProfilesMediumTest.java | 43 +++++--------- .../qualityprofile/db/QualityProfileDao.java | 34 +++++++---- .../qualityprofile/db/QualityProfileDto.java | 11 ++++ .../db/QualityProfileMapper.java | 16 ++++-- .../db/QualityProfileMapper.xml | 57 +++++++++++-------- .../db/QualityProfileDaoTest.java | 15 ++--- .../QualityProfileDaoTest/insert-result.xml | 2 +- .../db/QualityProfileDaoTest/projects.xml | 17 ++---- .../db/QualityProfileDaoTest/shared.xml | 5 +- 16 files changed, 154 insertions(+), 173 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileFactory.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileFactory.java index 47e23895ba4..f4ccf0a162d 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileFactory.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileFactory.java @@ -24,7 +24,6 @@ import org.apache.commons.lang.RandomStringUtils; import org.apache.commons.lang.StringUtils; import org.sonar.api.ServerComponent; import org.sonar.core.persistence.DbSession; -import org.sonar.core.properties.PropertyDto; import org.sonar.core.qualityprofile.db.QualityProfileDto; import org.sonar.server.db.DbClient; import org.sonar.server.exceptions.BadRequestException; @@ -32,7 +31,6 @@ import org.sonar.server.exceptions.Verifications; import org.sonar.server.util.Slug; import javax.annotation.CheckForNull; -import javax.annotation.Nullable; import java.util.Date; import java.util.List; @@ -42,8 +40,6 @@ import java.util.List; */ public class QProfileFactory implements ServerComponent { - private static final String PROFILE_PROPERTY_PREFIX = "sonar.profile."; - private final DbClient db; public QProfileFactory(DbClient db) { @@ -108,10 +104,9 @@ public class QProfileFactory implements ServerComponent { QualityProfileDto profile = db.qualityProfileDao().getNonNullByKey(session, key); List descendants = db.qualityProfileDao().findDescendants(session, key); if (!force) { - QualityProfileDto defaultProfile = getDefault(session, profile.getLanguage()); - checkNotDefault(defaultProfile, profile); + checkNotDefault(profile); for (QualityProfileDto descendant : descendants) { - checkNotDefault(defaultProfile, descendant); + checkNotDefault(descendant); } } // delete bottom-up @@ -124,7 +119,6 @@ public class QProfileFactory implements ServerComponent { private void doDelete(DbSession session, QualityProfileDto profile) { db.activeRuleDao().deleteByProfileKey(session, profile.getKey()); db.qualityProfileDao().delete(session, profile); - db.propertiesDao().deleteProjectProperties(PROFILE_PROPERTY_PREFIX + profile.getLanguage(), profile.getName(), session); } // ------------- DEFAULT PROFILE @@ -161,10 +155,11 @@ public class QProfileFactory implements ServerComponent { } private void setDefault(DbSession session, QualityProfileDto profile) { - PropertyDto property = new PropertyDto() - .setKey(PROFILE_PROPERTY_PREFIX + profile.getLanguage()) - .setValue(profile.getName()); - db.propertiesDao().setProperty(property, session); + QualityProfileDto previousDefault = db.qualityProfileDao().getDefaultProfile(profile.getLanguage(), session); + if (previousDefault != null) { + db.qualityProfileDao().update(session, previousDefault.setDefault(false)); + } + db.qualityProfileDao().update(session, profile.setDefault(true)); } QualityProfileDto getByProjectAndLanguage(String projectKey, String language) { @@ -178,7 +173,7 @@ public class QProfileFactory implements ServerComponent { @CheckForNull public QualityProfileDto getByProjectAndLanguage(DbSession session, String projectKey, String language) { - return db.qualityProfileDao().getByProjectAndLanguage(projectKey, language, PROFILE_PROPERTY_PREFIX + language, session); + return db.qualityProfileDao().getByProjectAndLanguage(projectKey, language, session); } QualityProfileDto getByNameAndLanguage(String name, String language) { @@ -195,8 +190,8 @@ public class QProfileFactory implements ServerComponent { return db.qualityProfileDao().getByNameAndLanguage(name, language, session); } - private void checkNotDefault(@Nullable QualityProfileDto defaultProfile, QualityProfileDto p) { - if (defaultProfile != null && defaultProfile.getKey().equals(p.getKey())) { + private void checkNotDefault(QualityProfileDto p) { + if (p.isDefault()) { throw new BadRequestException("The profile marked as default can not be deleted: " + p.getKey()); } } @@ -216,7 +211,6 @@ public class QProfileFactory implements ServerComponent { String previousName = profile.getName(); profile.setName(newName); db.qualityProfileDao().update(dbSession, profile); - db.propertiesDao().updateProperties(PROFILE_PROPERTY_PREFIX + profile.getLanguage(), previousName, newName, dbSession); dbSession.commit(); return true; } diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileProjectLookup.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileProjectLookup.java index 995580c36ea..712d94f4e49 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileProjectLookup.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileProjectLookup.java @@ -39,7 +39,6 @@ import java.util.Map; public class QProfileProjectLookup implements ServerComponent { - public static final String PROFILE_PROPERTY_PREFIX = "sonar.profile."; private final DbClient db; public QProfileProjectLookup(DbClient db) { @@ -52,9 +51,7 @@ public class QProfileProjectLookup implements ServerComponent { QualityProfileDto qualityProfile = db.qualityProfileDao().getById(profileId, session); QProfileValidations.checkProfileIsNotNull(qualityProfile); Map componentsByKeys = Maps.newHashMap(); - for (Component component : db.qualityProfileDao().selectProjects( - qualityProfile.getName(), PROFILE_PROPERTY_PREFIX + qualityProfile.getLanguage(), session - )) { + for (Component component : db.qualityProfileDao().selectProjects(qualityProfile.getName(), qualityProfile.getLanguage(), session)) { componentsByKeys.put(component.key(), component); } @@ -74,12 +71,12 @@ public class QProfileProjectLookup implements ServerComponent { } public int countProjects(QProfile profile) { - return db.qualityProfileDao().countProjects(profile.name(), PROFILE_PROPERTY_PREFIX + profile.language()); + return db.qualityProfileDao().countProjects(profile.name(), profile.language()); } @CheckForNull public QProfile findProfileByProjectAndLanguage(long projectId, String language) { - QualityProfileDto dto = db.qualityProfileDao().getByProjectAndLanguage(projectId, language, PROFILE_PROPERTY_PREFIX + language); + QualityProfileDto dto = db.qualityProfileDao().getByProjectAndLanguage(projectId, language); if (dto != null) { return QProfile.from(dto); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileProjectOperations.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileProjectOperations.java index c1c122c65a0..a2d71d79753 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileProjectOperations.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileProjectOperations.java @@ -26,7 +26,6 @@ import org.sonar.core.component.ComponentDto; import org.sonar.core.permission.GlobalPermissions; import org.sonar.core.persistence.DbSession; import org.sonar.core.persistence.MyBatis; -import org.sonar.core.properties.PropertyDto; import org.sonar.core.qualityprofile.db.QualityProfileDto; import org.sonar.server.db.DbClient; import org.sonar.server.exceptions.ForbiddenException; @@ -59,8 +58,7 @@ public class QProfileProjectOperations implements ServerComponent { checkPermission(userSession, project.key()); QualityProfileDto qualityProfile = findNotNull(profileId, session); - db.propertiesDao().setProperty(new PropertyDto().setKey( - QProfileProjectLookup.PROFILE_PROPERTY_PREFIX + qualityProfile.getLanguage()).setValue(qualityProfile.getName()).setResourceId(project.getId()), session); + db.qualityProfileDao().insertProjectProfileAssociation(project.uuid(), qualityProfile.getKey(), session); session.commit(); } @@ -71,7 +69,7 @@ public class QProfileProjectOperations implements ServerComponent { checkPermission(userSession, project.key()); QualityProfileDto qualityProfile = findNotNull(profileId, session); - db.propertiesDao().deleteProjectProperty(QProfileProjectLookup.PROFILE_PROPERTY_PREFIX + qualityProfile.getLanguage(), project.getId(), session); + db.qualityProfileDao().deleteProjectProfileAssociation(project.uuid(), qualityProfile.getKey(), session); session.commit(); } finally { MyBatis.closeQuietly(session); @@ -84,8 +82,11 @@ public class QProfileProjectOperations implements ServerComponent { ComponentDto project = db.componentDao().getById(projectId, session); checkPermission(userSession, project.key()); - db.propertiesDao().deleteProjectProperty(QProfileProjectLookup.PROFILE_PROPERTY_PREFIX + language, project.getId(), session); - session.commit(); + QualityProfileDto associatedProfile = db.qualityProfileDao().getByProjectAndLanguage(project.getKey(), language, session); + if (associatedProfile != null) { + db.qualityProfileDao().deleteProjectProfileAssociation(project.uuid(), associatedProfile.getKey(), session); + session.commit(); + } } finally { MyBatis.closeQuietly(session); } @@ -96,7 +97,7 @@ public class QProfileProjectOperations implements ServerComponent { DbSession session = db.openSession(false); try { QualityProfileDto qualityProfile = findNotNull(profileId, session); - db.propertiesDao().deleteProjectProperties(QProfileProjectLookup.PROFILE_PROPERTY_PREFIX + qualityProfile.getLanguage(), qualityProfile.getName(), session); + db.qualityProfileDao().deleteAllProjectProfileAssociation(qualityProfile.getKey(), session); session.commit(); } finally { MyBatis.closeQuietly(session); diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RegisterQualityProfiles.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RegisterQualityProfiles.java index 4655acaf905..1eb5b2b5e5b 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RegisterQualityProfiles.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RegisterQualityProfiles.java @@ -42,11 +42,8 @@ import org.sonar.server.db.DbClient; import org.sonar.server.platform.PersistentSettings; import javax.annotation.Nullable; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; + +import java.util.*; /** * Synchronize Quality profiles during server startup @@ -154,21 +151,17 @@ public class RegisterQualityProfiles implements ServerComponent { } private void setDefault(String language, List profileDefs, DbSession session) { - String propertyKey = "sonar.profile." + language; boolean upToDate = false; - String currentDefault = settings.getString(propertyKey); + QualityProfileDto currentDefault = dbClient.qualityProfileDao().getDefaultProfile(language, session); if (currentDefault != null) { - // check validity - QualityProfileDto profile = dbClient.qualityProfileDao().getByNameAndLanguage(currentDefault, language, session); - if (profile != null) { - upToDate = true; - } + upToDate = true; } if (!upToDate) { String defaultProfileName = nameOfDefaultProfile(profileDefs); LOGGER.info("Set default " + language + " profile: " + defaultProfileName); - settings.saveProperty(propertyKey, defaultProfileName); + QualityProfileDto newDefaultProfile = dbClient.qualityProfileDao().getByNameAndLanguage(defaultProfileName, language, session); + dbClient.qualityProfileDao().update(session, newDefaultProfile.setDefault(true)); } } 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 d8c10ef352b..829ad1a1dbd 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 @@ -453,7 +453,7 @@ public class ProjectRepositoryLoaderMediumTest { QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt( DateUtils.formatDateTime(ruleUpdatedAt)); tester.get(DbClient.class).qualityProfileDao().insert(dbSession, profileDto); - tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.profile.xoo").setValue("SonarQube way").setResourceId(project.getId()), dbSession); + tester.get(DbClient.class).qualityProfileDao().insertProjectProfileAssociation(project.uuid(), profileDto.getKee(), dbSession); dbSession.commit(); @@ -475,9 +475,8 @@ public class ProjectRepositoryLoaderMediumTest { tester.get(DbClient.class).componentDao().insert(dbSession, project); QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt( - DateUtils.formatDateTime(ruleUpdatedAt)); + DateUtils.formatDateTime(ruleUpdatedAt)).setDefault(true); tester.get(DbClient.class).qualityProfileDao().insert(dbSession, profileDto); - tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.profile.xoo").setValue("SonarQube way"), dbSession); dbSession.commit(); @@ -499,9 +498,8 @@ public class ProjectRepositoryLoaderMediumTest { tester.get(DbClient.class).componentDao().insert(dbSession, project); QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt( - DateUtils.formatDateTime(ruleUpdatedAt)); + DateUtils.formatDateTime(ruleUpdatedAt)).setDefault(true); tester.get(DbClient.class).qualityProfileDao().insert(dbSession, profileDto); - tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.profile.xoo").setValue("SonarQube way"), dbSession); dbSession.commit(); @@ -520,9 +518,8 @@ public class ProjectRepositoryLoaderMediumTest { Date ruleUpdatedAt = DateUtils.parseDateTime("2014-01-14T13:00:00+0100"); QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt( - DateUtils.formatDateTime(ruleUpdatedAt)); + DateUtils.formatDateTime(ruleUpdatedAt)).setDefault(true); tester.get(DbClient.class).qualityProfileDao().insert(dbSession, profileDto); - tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.profile.xoo").setValue("SonarQube way"), dbSession); dbSession.commit(); @@ -547,7 +544,7 @@ public class ProjectRepositoryLoaderMediumTest { QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt( DateUtils.formatDateTime(ruleUpdatedAt)); tester.get(DbClient.class).qualityProfileDao().insert(dbSession, profileDto); - tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.profile.xoo").setValue("SonarQube way").setResourceId(project.getId()), dbSession); + tester.get(DbClient.class).qualityProfileDao().insertProjectProfileAssociation(project.uuid(), profileDto.getKee(), dbSession); dbSession.commit(); @@ -582,9 +579,8 @@ public class ProjectRepositoryLoaderMediumTest { tester.get(DbClient.class).componentDao().insert(dbSession, project); QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt( - DateUtils.formatDateTime(DateUtils.parseDateTime("2014-01-14T13:00:00+0100"))); + DateUtils.formatDateTime(DateUtils.parseDateTime("2014-01-14T13:00:00+0100"))).setDefault(true); tester.get(DbClient.class).qualityProfileDao().insert(dbSession, profileDto); - tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.profile.xoo").setValue("SonarQube way"), dbSession); RuleKey ruleKey = RuleKey.of("squid", "AvoidCycle"); RuleDto rule = RuleTesting.newDto(ruleKey).setName("Avoid Cycle").setConfigKey("squid-1").setLanguage(ServerTester.Xoo.KEY); @@ -629,7 +625,7 @@ public class ProjectRepositoryLoaderMediumTest { tester.get(DbClient.class).qualityProfileDao().insert(dbSession, profileDto1, profileDto2); // The first profile is the profile used but the project - tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.profile.xoo").setResourceId(project.getId()).setValue(profileDto1.getName()), dbSession); + tester.get(DbClient.class).qualityProfileDao().insertProjectProfileAssociation(project.uuid(), profileDto1.getKee(), dbSession); tester.get(RuleActivator.class).activate(dbSession, new RuleActivation(ruleKey1).setSeverity(Severity.MINOR), profileDto1.getKey()); @@ -656,9 +652,8 @@ public class ProjectRepositoryLoaderMediumTest { tester.get(DbClient.class).componentDao().insert(dbSession, project); QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd") - .setRulesUpdatedAt(DateUtils.formatDateTime(DateUtils.parseDateTime("2014-01-14T13:00:00+0100"))); + .setRulesUpdatedAt(DateUtils.formatDateTime(DateUtils.parseDateTime("2014-01-14T13:00:00+0100"))).setDefault(true); tester.get(DbClient.class).qualityProfileDao().insert(dbSession, profileDto); - tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.profile.xoo").setValue("SonarQube way"), dbSession); for (int i = 0; i<20; i++) { RuleKey ruleKey = RuleKey.of("squid", "Rule" + i); @@ -681,9 +676,8 @@ public class ProjectRepositoryLoaderMediumTest { tester.get(DbClient.class).componentDao().insert(dbSession, project); QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt( - DateUtils.formatDateTime(ruleUpdatedAt)); + DateUtils.formatDateTime(ruleUpdatedAt)).setDefault(true); tester.get(DbClient.class).qualityProfileDao().insert(dbSession, profileDto); - tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.profile.xoo").setValue("SonarQube way"), dbSession); RuleKey ruleKey = RuleKey.of("squid", "ArchitecturalConstraint"); RuleDto templateRule = RuleTesting.newTemplateRule(ruleKey).setName("Architectural Constraint").setLanguage(ServerTester.Xoo.KEY); @@ -835,9 +829,8 @@ public class ProjectRepositoryLoaderMediumTest { private void addDefaultProfile() { QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt( - DateUtils.formatDateTime(new Date())); + DateUtils.formatDateTime(new Date())).setDefault(true); tester.get(DbClient.class).qualityProfileDao().insert(dbSession, profileDto); - tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.profile.xoo").setValue("SonarQube way"), dbSession); } private FileSourceDto newFileSourceDto(ComponentDto file) { diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileFactoryMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileFactoryMediumTest.java index 1028ae79a70..4e31be74ebd 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileFactoryMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileFactoryMediumTest.java @@ -27,7 +27,6 @@ import org.sonar.api.server.rule.RuleParamType; import org.sonar.core.component.ComponentDto; import org.sonar.core.permission.GlobalPermissions; import org.sonar.core.persistence.DbSession; -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; @@ -195,24 +194,6 @@ public class QProfileFactoryMediumTest { } } - @Test - public void renaming_is_applied_to_default_profile_properties() { - QualityProfileDto p1 = factory.create(dbSession, new QProfileName("xoo", "P1")); - db.propertiesDao().setProperty(new PropertyDto().setKey("sonar.profile.xoo").setValue("P1"), dbSession); - db.propertiesDao().setProperty(new PropertyDto().setKey("sonar.profile.java").setValue("P1"), dbSession); - db.propertiesDao().setProperty(new PropertyDto().setKey("sonar.profile.js").setValue("JS1"), dbSession); - dbSession.commit(); - dbSession.clearCache(); - - factory.rename(p1.getKey(), "P2"); - dbSession.clearCache(); - - // do not touch java and js profiles, even if java profile has same name - assertThat(db.propertiesDao().selectGlobalProperty("sonar.profile.xoo").getValue()).isEqualTo("P2"); - assertThat(db.propertiesDao().selectGlobalProperty("sonar.profile.java").getValue()).isEqualTo("P1"); - assertThat(db.propertiesDao().selectGlobalProperty("sonar.profile.js").getValue()).isEqualTo("JS1"); - } - @Test public void delete() { initRules(); @@ -305,13 +286,12 @@ public class QProfileFactoryMediumTest { dbSession.commit(); dbSession.clearCache(); - assertThat(db.propertiesDao().selectGlobalProperty("sonar.profile.xoo")).isNull(); - assertThat(factory.getDefault("xoo")).isNull(); + assertThat(db.qualityProfileDao().getByKey(dbSession, XOO_P1_KEY).isDefault()).isFalse(); factory.setDefault(XOO_P1_KEY); dbSession.clearCache(); - assertThat(db.propertiesDao().selectGlobalProperty("sonar.profile.xoo").getValue()).isEqualTo("P1"); - assertThat(factory.getDefault("xoo").getKey()).isEqualTo(XOO_P1_KEY); + + assertThat(db.qualityProfileDao().getByKey(dbSession, XOO_P1_KEY).isDefault()).isTrue(); } @Test @@ -329,6 +309,7 @@ public class QProfileFactoryMediumTest { public void get_profile_by_project_and_language() { ComponentDto project = new ComponentDto() .setId(1L) + .setUuid("ABCD") .setKey("org.codehaus.sonar:sonar") .setName("SonarQube") .setLongName("SonarQube") diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileProjectOperationsMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileProjectOperationsMediumTest.java index 37b02397f37..ddf0da41a08 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileProjectOperationsMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileProjectOperationsMediumTest.java @@ -50,6 +50,7 @@ public class QProfileProjectOperationsMediumTest { ComponentDto project; QualityProfileDto profile; static final String PROJECT_KEY = "SonarQube"; + static final String PROJECT_UUID = "ABCD"; UserSession authorizedProfileAdminUserSession = MockUserSession.create().setLogin("john").setName("John").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); UserSession authorizedProjectAdminUserSession = MockUserSession.create().setLogin("john").setName("John").addProjectPermissions(UserRole.ADMIN, PROJECT_KEY); @@ -63,6 +64,7 @@ public class QProfileProjectOperationsMediumTest { projectOperations = tester.get(QProfileProjectOperations.class); project = new ComponentDto() + .setUuid(PROJECT_UUID) .setKey(PROJECT_KEY) .setName("SonarQube") .setLongName("SonarQube") @@ -117,6 +119,7 @@ public class QProfileProjectOperationsMediumTest { @Test public void remove_all_projects() throws Exception { ComponentDto project1 = new ComponentDto() + .setUuid("BCDE") .setKey("project1") .setName("project1") .setLongName("project1") @@ -124,6 +127,7 @@ public class QProfileProjectOperationsMediumTest { .setScope("PRJ") .setEnabled(true); ComponentDto project2 = new ComponentDto() + .setUuid("CDEF") .setKey("project2") .setName("project2") .setLongName("project2") diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesMediumTest.java index be46ca7fc9c..8009d36adb5 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesMediumTest.java @@ -33,8 +33,6 @@ import org.sonar.api.server.rule.RuleParamType; import org.sonar.api.server.rule.RulesDefinition; import org.sonar.api.utils.ValidationMessages; import org.sonar.core.persistence.DbSession; -import org.sonar.core.properties.PropertiesDao; -import org.sonar.core.properties.PropertyDto; import org.sonar.core.qualityprofile.db.*; import org.sonar.core.template.LoadedTemplateDto; import org.sonar.server.db.DbClient; @@ -119,7 +117,7 @@ public class RegisterQualityProfilesMediumTest { assertThat(profile).isNotNull(); // Check Default Profile - verifyProperty("sonar.profile.xoo", "Basic"); + verifyDefaultProfile("xoo", "Basic"); // Check ActiveRules in DB ActiveRuleDao activeRuleDao = dbClient().activeRuleDao(); @@ -169,7 +167,7 @@ public class RegisterQualityProfilesMediumTest { tester = new ServerTester().addXoo().addComponents(new SimpleProfileDefinition("one", false), new SimpleProfileDefinition("two", true)); tester.start(); - verifyProperty("sonar.profile.xoo", "two"); + verifyDefaultProfile("xoo", "two"); } @Test @@ -177,22 +175,7 @@ public class RegisterQualityProfilesMediumTest { tester = new ServerTester().addXoo().addComponents(new SimpleProfileDefinition("Sonar way", false), new SimpleProfileDefinition("Other way", false)); tester.start(); - verifyProperty("sonar.profile.xoo", "Sonar way"); - } - - @Test - public void fix_default_profile_if_invalid() throws Exception { - tester = new ServerTester().addXoo().addComponents(new SimpleProfileDefinition("one", true)); - tester.start(); - - PropertiesDao propertiesDao = dbClient().propertiesDao(); - propertiesDao.updateProperties("sonar.profile.xoo", "one", "invalid"); - // -> properties are corrupted. Default profile "invalid" does not exist - verifyProperty("sonar.profile.xoo", "invalid"); - - tester.get(Platform.class).restart(); - // restart must resolve the pb - verifyProperty("sonar.profile.xoo", "one"); + verifyDefaultProfile("xoo", "Sonar way"); } @Test @@ -200,13 +183,17 @@ public class RegisterQualityProfilesMediumTest { tester = new ServerTester().addXoo().addComponents(new SimpleProfileDefinition("one", true), new SimpleProfileDefinition("two", false)); tester.start(); - PropertiesDao propertiesDao = dbClient().propertiesDao(); - propertiesDao.updateProperties("sonar.profile.xoo", "one", "two"); - verifyProperty("sonar.profile.xoo", "two"); + QualityProfileDao profileDao = dbClient().qualityProfileDao(); + DbSession session = dbClient().openSession(false); + QualityProfileDto profileTwo = profileDao.getByNameAndLanguage("two", "xoo", session); + tester.get(QProfileFactory.class).setDefault(session, profileTwo.getKee()); + session.commit(); + + verifyDefaultProfile("xoo", "two"); tester.get(Platform.class).restart(); // restart must keep "two" as default profile, even if "one" is marked as it - verifyProperty("sonar.profile.xoo", "two"); + verifyDefaultProfile("xoo", "two"); } /** @@ -229,10 +216,10 @@ public class RegisterQualityProfilesMediumTest { // do not fail } - private void verifyProperty(String key, String value) { - PropertyDto prop = dbClient().propertiesDao().selectGlobalProperty(key); - assertThat(prop).isNotNull(); - assertThat(prop.getValue()).isEqualTo(value); + private void verifyDefaultProfile(String language, String name) { + QualityProfileDto defaultProfile = dbClient().qualityProfileDao().getDefaultProfile(language); + assertThat(defaultProfile).isNotNull(); + assertThat(defaultProfile.getName()).isEqualTo(name); } private DbClient dbClient() { diff --git a/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileDao.java b/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileDao.java index 01244ef1ae2..219b2147990 100644 --- a/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileDao.java +++ b/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileDao.java @@ -170,7 +170,7 @@ public class QualityProfileDao implements ServerComponent, DaoComponent { @CheckForNull public QualityProfileDto getDefaultProfile(String language, DbSession session) { - return session.getMapper(QualityProfileMapper.class).selectDefaultProfile(language, String.format("sonar.profile.%s", language)); + return session.getMapper(QualityProfileMapper.class).selectDefaultProfile(language); } @CheckForNull @@ -184,18 +184,18 @@ public class QualityProfileDao implements ServerComponent, DaoComponent { } @CheckForNull - public QualityProfileDto getByProjectAndLanguage(long projectId, String language, String key) { + public QualityProfileDto getByProjectAndLanguage(long projectId, String language) { DbSession session = mybatis.openSession(false); try { - return session.getMapper(QualityProfileMapper.class).selectByProjectIdAndLanguage(projectId, language, key); + return session.getMapper(QualityProfileMapper.class).selectByProjectIdAndLanguage(projectId, language); } finally { MyBatis.closeQuietly(session); } } @CheckForNull - public QualityProfileDto getByProjectAndLanguage(String projectKey, String language, String propertyKeyPrefix, DbSession session) { - return session.getMapper(QualityProfileMapper.class).selectByProjectAndLanguage(projectKey, language, propertyKeyPrefix); + public QualityProfileDto getByProjectAndLanguage(String projectKey, String language, DbSession session) { + return session.getMapper(QualityProfileMapper.class).selectByProjectAndLanguage(projectKey, language); } public List findByLanguage(String language) { @@ -297,25 +297,37 @@ public class QualityProfileDao implements ServerComponent, DaoComponent { } } - public List selectProjects(String propertyKey, String propertyValue) { + public List selectProjects(String profileName, String language) { DbSession session = mybatis.openSession(false); try { - return selectProjects(propertyKey, propertyValue, session); + return selectProjects(profileName, language, session); } finally { MyBatis.closeQuietly(session); } } - public List selectProjects(String propertyKey, String propertyValue, DbSession session) { - return session.getMapper(QualityProfileMapper.class).selectProjects(propertyKey, propertyValue); + public List selectProjects(String profileName, String language, DbSession session) { + return session.getMapper(QualityProfileMapper.class).selectProjects(profileName, language); } - public int countProjects(String propertyKey, String propertyValue) { + public int countProjects(String profileName, String language) { DbSession session = mybatis.openSession(false); try { - return session.getMapper(QualityProfileMapper.class).countProjects(propertyKey, propertyValue); + return session.getMapper(QualityProfileMapper.class).countProjects(profileName, language); } finally { MyBatis.closeQuietly(session); } } + + public void insertProjectProfileAssociation(String projectUuid, String profileKey, DbSession session) { + session.getMapper(QualityProfileMapper.class).insertProjectProfileAssociation(projectUuid, profileKey); + } + + public void deleteProjectProfileAssociation(String projectUuid, String profileKey, DbSession session) { + session.getMapper(QualityProfileMapper.class).deleteProjectProfileAssociation(projectUuid, profileKey); + } + + public void deleteAllProjectProfileAssociation(String profileKey, DbSession session) { + session.getMapper(QualityProfileMapper.class).deleteAllProjectProfileAssociation(profileKey); + } } diff --git a/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileDto.java b/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileDto.java index b11695a519a..ae43582e405 100644 --- a/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileDto.java +++ b/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileDto.java @@ -25,6 +25,7 @@ import org.sonar.core.persistence.Dto; import javax.annotation.CheckForNull; import javax.annotation.Nullable; + import java.util.Date; public class QualityProfileDto extends Dto { @@ -35,6 +36,7 @@ public class QualityProfileDto extends Dto { private String language; private String parentKee; private String rulesUpdatedAt; + private boolean isDefault; /** * @deprecated use {@link #createFor(String)} @@ -113,6 +115,15 @@ public class QualityProfileDto extends Dto { return this; } + public boolean isDefault() { + return isDefault; + } + + public QualityProfileDto setDefault(boolean isDefault) { + this.isDefault = isDefault; + return this; + } + public static QualityProfileDto createFor(String key) { return new QualityProfileDto().setKee(key); } diff --git a/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileMapper.java b/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileMapper.java index 3ba36880451..2dfc8aa9542 100644 --- a/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileMapper.java +++ b/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileMapper.java @@ -38,7 +38,7 @@ public interface QualityProfileMapper { List selectAll(); @CheckForNull - QualityProfileDto selectDefaultProfile(@Param("language") String language, @Param("propKey") String propKey); + QualityProfileDto selectDefaultProfile(@Param("language") String language); @CheckForNull QualityProfileDto selectByNameAndLanguage(@Param("name") String name, @Param("language") String language); @@ -63,11 +63,17 @@ public interface QualityProfileMapper { // PROJECTS - List selectProjects(@Param("value") String propertyValue, @Param("key") String propertyKey); + List selectProjects(@Param("profileName") String profileName, @Param("language") String language); - int countProjects(@Param("value") String propertyValue, @Param("key") String propertyKey); + int countProjects(@Param("profileName") String profileName, @Param("language") String language); - QualityProfileDto selectByProjectIdAndLanguage(@Param("projectId") Long projectId, @Param("language") String language, @Param("key") String propertyKeyPrefix); + QualityProfileDto selectByProjectIdAndLanguage(@Param("projectId") Long projectId, @Param("language") String language); - QualityProfileDto selectByProjectAndLanguage(@Param("projectKey") String projectKey, @Param("language") String language, @Param("propertyKey") String propertyKeyPrefix); + QualityProfileDto selectByProjectAndLanguage(@Param("projectKey") String projectKey, @Param("language") String language); + + void insertProjectProfileAssociation(@Param("projectUuid") String projectUuid, @Param("profileKey") String profileKey); + + void deleteProjectProfileAssociation(@Param("projectUuid") String projectUuid, @Param("profileKey") String profileKey); + + void deleteAllProjectProfileAssociation(@Param("profileKey") String profileKey); } diff --git a/sonar-core/src/main/resources/org/sonar/core/qualityprofile/db/QualityProfileMapper.xml b/sonar-core/src/main/resources/org/sonar/core/qualityprofile/db/QualityProfileMapper.xml index b8a6ea50889..8d76a86144f 100644 --- a/sonar-core/src/main/resources/org/sonar/core/qualityprofile/db/QualityProfileMapper.xml +++ b/sonar-core/src/main/resources/org/sonar/core/qualityprofile/db/QualityProfileMapper.xml @@ -9,20 +9,22 @@ p.name as name, p.language as language, p.parent_kee as parentKee, + p.is_default as isDefault, p.created_at as createdAt, p.updated_at as updatedAt, p.rules_updated_at as rulesUpdatedAt - INSERT INTO rules_profiles (kee, parent_kee, name, language, created_at, updated_at, rules_updated_at) - VALUES (#{kee}, #{parentKee}, #{name}, #{language}, #{createdAt}, #{updatedAt}, #{rulesUpdatedAt,}) + INSERT INTO rules_profiles (kee, parent_kee, name, language, is_default, created_at, updated_at, rules_updated_at) + VALUES (#{kee}, #{parentKee}, #{name}, #{language}, #{isDefault}, #{createdAt}, #{updatedAt}, #{rulesUpdatedAt,}) UPDATE rules_profiles SET name=#{name}, language=#{language}, + is_default=#{isDefault}, parent_kee=#{parentKee}, updated_at=#{updatedAt}, rules_updated_at=#{rulesUpdatedAt} @@ -86,54 +88,61 @@ + + INSERT INTO project_profiles (project_uuid, profile_key) VALUES (#{projectUuid}, #{profileKey}) + + + + DELETE FROM project_profiles WHERE project_uuid=#{projectUuid} AND profile_key=#{profileKey} + + + + DELETE FROM project_profiles WHERE profile_key=#{profileKey} + + diff --git a/sonar-core/src/test/java/org/sonar/core/qualityprofile/db/QualityProfileDaoTest.java b/sonar-core/src/test/java/org/sonar/core/qualityprofile/db/QualityProfileDaoTest.java index ea836070470..7518834fdd7 100644 --- a/sonar-core/src/test/java/org/sonar/core/qualityprofile/db/QualityProfileDaoTest.java +++ b/sonar-core/src/test/java/org/sonar/core/qualityprofile/db/QualityProfileDaoTest.java @@ -73,7 +73,8 @@ public class QualityProfileDaoTest extends AbstractDaoTestCase { .setId(1) .setName("New Name") .setLanguage("js") - .setParentKee("fghij"); + .setParentKee("fghij") + .setDefault(false); dao.update(dto); @@ -214,21 +215,21 @@ public class QualityProfileDaoTest extends AbstractDaoTestCase { public void select_projects() { setupData("projects"); - assertThat(dao.selectProjects("Sonar Way", "sonar.profile.java")).hasSize(2); + assertThat(dao.selectProjects("Sonar Way", "java")).hasSize(2); } @Test public void count_projects() { setupData("projects"); - assertThat(dao.countProjects("Sonar Way", "sonar.profile.java")).isEqualTo(2); + assertThat(dao.countProjects("Sonar Way", "java")).isEqualTo(2); } @Test public void select_by_project_id_and_language() { setupData("projects"); - QualityProfileDto dto = dao.getByProjectAndLanguage(1L, "java", "sonar.profile.java"); + QualityProfileDto dto = dao.getByProjectAndLanguage(1L, "java"); assertThat(dto.getId()).isEqualTo(1); } @@ -236,10 +237,10 @@ public class QualityProfileDaoTest extends AbstractDaoTestCase { public void select_by_project_key_and_language() { setupData("projects"); - QualityProfileDto dto = dao.getByProjectAndLanguage("org.codehaus.sonar:sonar", "java", "sonar.profile.java", session); + QualityProfileDto dto = dao.getByProjectAndLanguage("org.codehaus.sonar:sonar", "java", session); assertThat(dto.getId()).isEqualTo(1); - assertThat(dao.getByProjectAndLanguage("org.codehaus.sonar:sonar", "unkown", "sonar.profile.java", session)).isNull(); - assertThat(dao.getByProjectAndLanguage("unknown", "java", "sonar.profile.java", session)).isNull(); + assertThat(dao.getByProjectAndLanguage("org.codehaus.sonar:sonar", "unkown", session)).isNull(); + assertThat(dao.getByProjectAndLanguage("unknown", "java", session)).isNull(); } } diff --git a/sonar-core/src/test/resources/org/sonar/core/qualityprofile/db/QualityProfileDaoTest/insert-result.xml b/sonar-core/src/test/resources/org/sonar/core/qualityprofile/db/QualityProfileDaoTest/insert-result.xml index 90f86af8a4a..8a9e9ce1ada 100644 --- a/sonar-core/src/test/resources/org/sonar/core/qualityprofile/db/QualityProfileDaoTest/insert-result.xml +++ b/sonar-core/src/test/resources/org/sonar/core/qualityprofile/db/QualityProfileDaoTest/insert-result.xml @@ -1,6 +1,6 @@ - - - - - - - - - - - - + + + + diff --git a/sonar-core/src/test/resources/org/sonar/core/qualityprofile/db/QualityProfileDaoTest/shared.xml b/sonar-core/src/test/resources/org/sonar/core/qualityprofile/db/QualityProfileDaoTest/shared.xml index ec98099a8a6..bf8e0113b24 100644 --- a/sonar-core/src/test/resources/org/sonar/core/qualityprofile/db/QualityProfileDaoTest/shared.xml +++ b/sonar-core/src/test/resources/org/sonar/core/qualityprofile/db/QualityProfileDaoTest/shared.xml @@ -1,12 +1,9 @@ - - - - -- 2.39.5