return mapper(dbSession).selectByQuery(query);
}
- public int countForQProfileUuid(DbSession dbSession, String profileUuid) {
- return mapper(dbSession).countForQProfileUuid(profileUuid);
+ /**
+ * Note: offset and limit of the query object will be ignored
+ */
+ public int countByQuery(DbSession dbSession, QProfileChangeQuery query) {
+ return mapper(dbSession).countByQuery(query);
}
public void deleteByRulesProfileUuids(DbSession dbSession, Collection<String> ruleProfileUuids) {
List<QProfileChangeDto> selectByQuery(@Param("query") QProfileChangeQuery query);
- int countForQProfileUuid(@Param("qProfileUuid") String qProfileUuid);
+ int countByQuery(@Param("query") QProfileChangeQuery query);
void deleteByRuleProfileUuids(@Param("ruleProfileUuids") Collection<String> uuids);
}
)
</insert>
- <select id="countForQProfileUuid" resultType="int">
+ <select id="countByQuery" resultType="int">
select count(qpc.kee)
- from qprofile_changes qpc
- inner join rules_profiles rp on rp.kee = qpc.rules_profile_uuid
- inner join org_qprofiles oqp on oqp.rules_profile_uuid = rp.kee
- where
- oqp.uuid = #{qProfileUuid, jdbcType=VARCHAR}
+ <include refid="sqlSelectByQuery" />
</select>
<select id="selectByQuery" resultType="org.sonar.db.qualityprofile.QProfileChangeDto">
+ select <include refid="selectColumns" />
<include refid="sqlSelectByQuery" />
+ order by qpc.created_at desc
limit #{query.limit}
offset #{query.offset}
</select>
<select id="selectByQuery" databaseId="mssql" resultType="org.sonar.db.qualityprofile.QProfileChangeDto">
+ select <include refid="selectColumns" />
<include refid="sqlSelectByQuery" />
+ order by qpc.created_at desc
offset #{query.offset} rows
fetch next #{query.limit} rows only
</select>
<select id="selectByQuery" databaseId="oracle" resultType="org.sonar.db.qualityprofile.QProfileChangeDto">
select "uuid", rulesProfileUuid, createdAt, login, changeType, data from (
select rownum rnum, "uuid", rulesProfileUuid, createdAt, login, changeType, data from (
+ select <include refid="selectColumns" />
<include refid="sqlSelectByQuery" />
+ order by qpc.created_at desc
)
where rownum <= #{query.total}
)
</select>
<sql id="sqlSelectByQuery">
- select <include refid="selectColumns" />
from qprofile_changes qpc
inner join rules_profiles rp on rp.kee = qpc.rules_profile_uuid
inner join org_qprofiles oqp on oqp.rules_profile_uuid = rp.kee
<if test="query.toExcluded != null">
and qpc.created_at < #{query.toExcluded}
</if>
- order by qpc.created_at desc
</sql>
<delete id="deleteByRuleProfileUuids" parameterType="String">
}
@Test
- public void countForQProfileUuid() {
+ public void countByQuery() {
QProfileDto profile1 = db.qualityProfiles().insert(db.getDefaultOrganization());
QProfileDto profile2 = db.qualityProfiles().insert(db.getDefaultOrganization());
+ long start = system2.now();
insertChange(profile1, "ACTIVATED", null, null);
insertChange(profile1, "ACTIVATED", null, null);
insertChange(profile2, "ACTIVATED", null, null);
+ long end = system2.now();
- assertThat(underTest.countForQProfileUuid(dbSession, profile1.getKee())).isEqualTo(2);
- assertThat(underTest.countForQProfileUuid(dbSession, profile2.getKee())).isEqualTo(1);
- assertThat(underTest.countForQProfileUuid(dbSession, "does_not_exist")).isEqualTo(0);
+ assertThat(underTest.countByQuery(dbSession, new QProfileChangeQuery(profile1.getKee()))).isEqualTo(2);
+ assertThat(underTest.countByQuery(dbSession, new QProfileChangeQuery(profile2.getKee()))).isEqualTo(1);
+ assertThat(underTest.countByQuery(dbSession, new QProfileChangeQuery("does_not_exist"))).isEqualTo(0);
+
+ QProfileChangeQuery query = new QProfileChangeQuery(profile1.getKee());
+ query.setToExcluded(start);
+ assertThat(underTest.countByQuery(dbSession, query)).isEqualTo(0);
+
+ QProfileChangeQuery query2 = new QProfileChangeQuery(profile1.getKee());
+ query2.setToExcluded(end);
+ assertThat(underTest.countByQuery(dbSession, query2)).isEqualTo(2);
}
@Test
underTest.deleteByRulesProfileUuids(dbSession, asList(profile1.getRulesProfileUuid()));
- assertThat(underTest.countForQProfileUuid(dbSession, profile1.getKee())).isEqualTo(0);
- assertThat(underTest.countForQProfileUuid(dbSession, profile2.getKee())).isEqualTo(1);
+ assertThat(underTest.countByQuery(dbSession, new QProfileChangeQuery(profile1.getKee()))).isEqualTo(0);
+ assertThat(underTest.countByQuery(dbSession, new QProfileChangeQuery(profile2.getKee()))).isEqualTo(1);
}
@Test
underTest.deleteByRulesProfileUuids(dbSession, asList("does not exist"));
- assertThat(underTest.countForQProfileUuid(dbSession, profile1.getKee())).isEqualTo(1);
+ assertThat(underTest.countByQuery(dbSession, new QProfileChangeQuery(profile1.getKee()))).isEqualTo(1);
}
private QProfileChangeDto insertChange(QProfileDto profile, String type, @Nullable String login, @Nullable String data) {
int pageSize = request.mandatoryParamAsInt(Param.PAGE_SIZE);
query.setPage(page, pageSize);
- int total = dbClient.qProfileChangeDao().countForQProfileUuid(dbSession, query.getProfileUuid());
+ int total = dbClient.qProfileChangeDao().countByQuery(dbSession, query);
List<Change> changelogs = load(dbSession, query);
writeResponse(response.newJsonWriter(), total, page, pageSize, changelogs);
import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_LANGUAGE;
import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_ORGANIZATION;
import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_QUALITY_PROFILE;
+import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_SINCE;
public class ChangelogActionTest {
assertThat(response).contains("\"total\":1");
}
+ @Test
+ public void changelog_filter_by_since() throws Exception {
+ QProfileDto qualityProfile = dbTester.qualityProfiles().insert(organization);
+ system2.setNow(DateUtils.parseDateTime("2011-04-25T01:15:42+0100").getTime());
+ QProfileChangeDto change = QualityProfileTesting.newQProfileChangeDto()
+ .setUuid(null)
+ .setCreatedAt(0)
+ .setRulesProfileUuid(qualityProfile.getRulesProfileUuid());
+ DbSession session = dbTester.getSession();
+ dbTester.getDbClient().qProfileChangeDao().insert(session, change);
+ session.commit();
+
+ String response = ws.newRequest()
+ .setMethod("GET")
+ .setParam(PARAM_KEY, qualityProfile.getKee())
+ .setParam(PARAM_SINCE, "2011-04-25T01:15:42+0100")
+ .execute()
+ .getInput();
+
+ assertThat(response).contains("\"total\":1");
+
+ String response2 = ws.newRequest()
+ .setMethod("GET")
+ .setParam(PARAM_KEY, qualityProfile.getKee())
+ .setParam(PARAM_SINCE, "2011-04-25T01:15:43+0100")
+ .execute()
+ .getInput();
+
+ assertThat(response2).contains("\"total\":0");
+ }
+
@Test
public void sort_changelog_events_in_reverse_chronological_order() {
QProfileDto profile = dbTester.qualityProfiles().insert(organization);
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonarqube.ws.client.qualityprofile;
+
+public class ChangelogWsRequest {
+
+ private final String language;
+ private final String organization;
+ private final Integer p;
+ private final Integer ps;
+ private final String qualityProfile;
+ private final String since;
+ private final String to;
+
+ private ChangelogWsRequest(Builder builder) {
+ this.language = builder.language;
+ this.organization = builder.organization;
+ this.p = builder.p;
+ this.ps = builder.ps;
+ this.qualityProfile = builder.qualityProfile;
+ this.since = builder.since;
+ this.to = builder.to;
+ }
+
+ public String getLanguage() {
+ return language;
+ }
+
+ public String getOrganization() {
+ return organization;
+ }
+
+ public Integer getP() {
+ return p;
+ }
+
+ public Integer getPs() {
+ return ps;
+ }
+
+ public String getQualityProfile() {
+ return qualityProfile;
+ }
+
+ public String getSince() {
+ return since;
+ }
+
+ public String getTo() {
+ return to;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private String language;
+ private String organization;
+ private Integer p;
+ private Integer ps;
+ private String qualityProfile;
+ private String since;
+ private String to;
+
+ private Builder() {
+ }
+
+ public Builder setLanguage(String language) {
+ this.language = language;
+ return this;
+ }
+
+ public Builder setOrganization(String organization) {
+ this.organization = organization;
+ return this;
+ }
+
+ public Builder setP(Integer p) {
+ this.p = p;
+ return this;
+ }
+
+ public Builder setPs(Integer ps) {
+ this.ps = ps;
+ return this;
+ }
+
+ public Builder setQualityProfile(String qualityProfile) {
+ this.qualityProfile = qualityProfile;
+ return this;
+ }
+
+ public Builder setSince(String since) {
+ this.since = since;
+ return this;
+ }
+
+ public Builder setTo(String to) {
+ this.to = to;
+ return this;
+ }
+
+ public ChangelogWsRequest build() {
+ return new ChangelogWsRequest(this);
+ }
+ }
+}
import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_DEFAULTS;
import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_FROM_KEY;
import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_GROUP;
+import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_KEY;
import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_LANGUAGE;
-import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_NAME;
import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_LOGIN;
+import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_NAME;
import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_ORGANIZATION;
import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_PARAMS;
-import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_PARENT_QUALITY_PROFILE;
import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_PARENT_KEY;
-import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_KEY;
-import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_QUALITY_PROFILE;
+import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_PARENT_QUALITY_PROFILE;
import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_PROJECT_KEY;
import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_PROJECT_UUID;
import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_QUALITY_PROFILE;
.setParam(PAGE_SIZE, request.getPageSize()),
SearchGroupsResponse.parser());
}
+
+ public String changelog(ChangelogWsRequest request) {
+ PostRequest postRequest = new PostRequest(path("changelog"))
+ .setParam("language", request.getLanguage())
+ .setParam("organization", request.getOrganization())
+ .setParam("qualityProfile", request.getQualityProfile());
+ if (request.getP() != null) {
+ postRequest.setParam("p", request.getP());
+ }
+ if (request.getPs() != null) {
+ postRequest.setParam("ps", request.getPs());
+ }
+ if (request.getSince() != null) {
+ postRequest.setParam("since", request.getSince());
+ }
+ if (request.getTo() != null) {
+ postRequest.setParam("to", request.getTo());
+ }
+ return call(postRequest).content();
+ }
}
import com.sonar.orchestrator.Orchestrator;
import java.util.function.Predicate;
+import org.json.JSONException;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
+import org.skyscreamer.jsonassert.JSONAssert;
+import org.skyscreamer.jsonassert.JSONCompareMode;
import org.sonarqube.tests.Category6Suite;
import org.sonarqube.tests.Tester;
import org.sonarqube.ws.Organizations.Organization;
import org.sonarqube.ws.client.GetRequest;
import org.sonarqube.ws.client.PostRequest;
import org.sonarqube.ws.client.WsResponse;
+import org.sonarqube.ws.client.qualityprofile.ChangelogWsRequest;
import org.sonarqube.ws.client.qualityprofile.SearchWsRequest;
import org.sonarqube.ws.client.qualityprofile.ShowRequest;
private static final String RULE_ONE_BUG_PER_LINE = "xoo:OneBugIssuePerLine";
private static final String RULE_ONE_ISSUE_PER_LINE = "xoo:OneIssuePerLine";
+ private static final String EXPECTED_CHANGELOG = "{\"total\":2,\"p\":1,\"ps\":50,\"events\":[" +
+ "{\"authorLogin\":\"admin\",\"authorName\":\"Administrator\",\"action\":\"ACTIVATED\",\"ruleKey\":\"xoo:OneIssuePerLine\",\"ruleName\":\"One Issue Per Line\",\"params\":{\"severity\":\"MAJOR\"}}," +
+ "{\"authorLogin\":\"admin\",\"authorName\":\"Administrator\",\"action\":\"ACTIVATED\",\"ruleKey\":\"xoo:OneBugIssuePerLine\",\"ruleName\":\"One Bug Issue Per Line\",\"params\":{\"severity\":\"MAJOR\"}}" +
+ "]}";
+ private static final String EXPECTED_CHANGELOG_EMPTY = "{\"total\":0,\"p\":1,\"ps\":50,\"events\":[]}";
+
@ClassRule
public static Orchestrator orchestrator = Category6Suite.ORCHESTRATOR;
.isEqualTo("xoo -> empty -> 0");
}
+ @Test
+ public void changelog() throws JSONException {
+ Organization org = tester.organizations().generate();
+ CreateWsResponse.QualityProfile profile = tester.qProfiles().createXooProfile(org);
+
+ String changelog = tester.wsClient().qualityProfiles().changelog(ChangelogWsRequest.builder()
+ .setOrganization(org.getKey())
+ .setLanguage(profile.getLanguage())
+ .setQualityProfile(profile.getName())
+ .build());
+ JSONAssert.assertEquals(EXPECTED_CHANGELOG_EMPTY, changelog, JSONCompareMode.STRICT);
+
+ tester.qProfiles().activateRule(profile, RULE_ONE_BUG_PER_LINE);
+ tester.qProfiles().activateRule(profile, RULE_ONE_ISSUE_PER_LINE);
+
+ String changelog2 = tester.wsClient().qualityProfiles().changelog(ChangelogWsRequest.builder()
+ .setOrganization(org.getKey())
+ .setLanguage(profile.getLanguage())
+ .setQualityProfile(profile.getName())
+ .build());
+ JSONAssert.assertEquals(EXPECTED_CHANGELOG, changelog2, JSONCompareMode.LENIENT);
+
+ String changelog3 = tester.wsClient().qualityProfiles().changelog(ChangelogWsRequest.builder()
+ .setOrganization(org.getKey())
+ .setLanguage(profile.getLanguage())
+ .setQualityProfile(profile.getName())
+ .setSince("2999-12-31T23:59:59+0000")
+ .build());
+ JSONAssert.assertEquals(EXPECTED_CHANGELOG_EMPTY, changelog3, JSONCompareMode.STRICT);
+ }
+
private SearchWsResponse.QualityProfile getProfile(Organization organization, Predicate<SearchWsResponse.QualityProfile> filter) {
return tester.qProfiles().service().search(new SearchWsRequest()
.setOrganizationKey(organization.getKey())).getProfilesList()