diff options
author | Sébastien Lesaint <sebastien.lesaint@sonarsource.com> | 2017-03-22 11:49:05 +0100 |
---|---|---|
committer | Sébastien Lesaint <sebastien.lesaint@sonarsource.com> | 2017-03-23 17:54:56 +0100 |
commit | 4b25bc908dd178cd656002d28851e0b4ec0fdb95 (patch) | |
tree | 7333cb447297829344de9af5369dc7bcb299a6cf /server/sonar-db-dao | |
parent | f63f13424bb24c5b3e825e12b0f9b0cea125d4f8 (diff) | |
download | sonarqube-4b25bc908dd178cd656002d28851e0b4ec0fdb95.tar.gz sonarqube-4b25bc908dd178cd656002d28851e0b4ec0fdb95.zip |
SONAR-8867 read and write into table RULES_METADATA
Diffstat (limited to 'server/sonar-db-dao')
7 files changed, 383 insertions, 85 deletions
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDao.java index 3aa63aff07d..1323982ceec 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDao.java @@ -22,6 +22,7 @@ package org.sonar.db.rule; import com.google.common.base.Optional; import java.util.Collection; import java.util.List; +import javax.annotation.Nullable; import org.apache.ibatis.session.ResultHandler; import org.sonar.api.rule.RuleKey; import org.sonar.api.rules.RuleQuery; @@ -35,7 +36,9 @@ import static org.sonar.db.DatabaseUtils.executeLargeInputs; public class RuleDao implements Dao { public Optional<RuleDto> selectByKey(DbSession session, String organizationUuid, RuleKey key) { - return Optional.fromNullable(mapper(session).selectByKey(key)); + RuleDto res = mapper(session).selectByKey(organizationUuid, key); + ensureOrganizationIsSet(organizationUuid, res); + return Optional.fromNullable(res); } public Optional<RuleDefinitionDto> selectDefinitionByKey(DbSession session, RuleKey key) { @@ -43,10 +46,11 @@ public class RuleDao implements Dao { } public RuleDto selectOrFailByKey(DbSession session, String organizationUuid, RuleKey key) { - RuleDto rule = mapper(session).selectByKey(key); + RuleDto rule = mapper(session).selectByKey(organizationUuid, key); if (rule == null) { throw new RowNotFoundException(String.format("Rule with key '%s' does not exist", key)); } + ensureOrganizationIsSet(organizationUuid, rule); return rule; } @@ -59,7 +63,9 @@ public class RuleDao implements Dao { } public Optional<RuleDto> selectById(long id, String organizationUuid, DbSession session) { - return Optional.fromNullable(mapper(session).selectById(id)); + RuleDto res = mapper(session).selectById(organizationUuid, id); + ensureOrganizationIsSet(organizationUuid, res); + return Optional.fromNullable(res); } public Optional<RuleDefinitionDto> selectDefinitionById(long id, DbSession session) { @@ -67,7 +73,9 @@ public class RuleDao implements Dao { } public List<RuleDto> selectByIds(DbSession session, String organizationUuid, List<Integer> ids) { - return executeLargeInputs(ids, mapper(session)::selectByIds); + return ensureOrganizationIsSet( + organizationUuid, + executeLargeInputs(ids, chunk -> mapper(session).selectByIds(organizationUuid, chunk))); } public List<RuleDefinitionDto> selectDefinitionByIds(DbSession session, List<Integer> ids) { @@ -75,7 +83,8 @@ public class RuleDao implements Dao { } public List<RuleDto> selectByKeys(DbSession session, String organizationUuid, Collection<RuleKey> keys) { - return executeLargeInputs(keys, mapper(session)::selectByKeys); + return ensureOrganizationIsSet(organizationUuid, + executeLargeInputs(keys, chunk -> mapper(session).selectByKeys(organizationUuid, chunk))); } public List<RuleDefinitionDto> selectDefinitionByKeys(DbSession session, Collection<RuleKey> keys) { @@ -87,7 +96,7 @@ public class RuleDao implements Dao { } public List<RuleDto> selectAll(DbSession session, String organizationUuid) { - return mapper(session).selectAll(); + return ensureOrganizationIsSet(organizationUuid, mapper(session).selectAll(organizationUuid)); } public List<RuleDefinitionDto> selectAllDefinitions(DbSession session) { @@ -95,11 +104,22 @@ public class RuleDao implements Dao { } public List<RuleDto> selectByQuery(DbSession session, String organizationUuid, RuleQuery ruleQuery) { - return mapper(session).selectByQuery(ruleQuery); + return ensureOrganizationIsSet(organizationUuid, mapper(session).selectByQuery(organizationUuid, ruleQuery)); + } + + private static void ensureOrganizationIsSet(String organizationUuid, @Nullable RuleDto res) { + if (res != null) { + res.setOrganizationUuid(organizationUuid); + } + } + + private static List<RuleDto> ensureOrganizationIsSet(String organizationUuid, List<RuleDto> res) { + res.forEach(dto -> ensureOrganizationIsSet(organizationUuid, dto)); + return res; } public void insert(DbSession session, RuleDefinitionDto dto) { - mapper(session).insert(dto); + mapper(session).insertDefinition(dto); } public void update(DbSession session, RuleDefinitionDto dto) { @@ -107,7 +127,11 @@ public class RuleDao implements Dao { } public void update(DbSession session, RuleMetadataDto dto) { - mapper(session).updateMetadata(dto); + if (mapper(session).countMetadata(dto) > 0) { + mapper(session).updateMetadata(dto); + } else { + mapper(session).insertMetadata(dto); + } } private static RuleMapper mapper(DbSession session) { diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java index 962537dd74e..66267ab3e96 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java @@ -19,7 +19,6 @@ */ package org.sonar.db.rule; -import java.util.Date; import java.util.Set; import javax.annotation.CheckForNull; import javax.annotation.Nullable; @@ -234,15 +233,45 @@ public class RuleDto { return this; } + public Set<String> getSystemTags() { + return definition.getSystemTags(); + } + + /** + * Used in MyBatis mapping. + */ + private void setSystemTagsField(String s) { + definition.setSystemTagsField(s); + } + public long getCreatedAt() { return definition.getCreatedAt(); } public RuleDto setCreatedAt(long createdAt) { definition.setCreatedAt(createdAt); + metadata.setCreatedAt(createdAt); return this; } + /** + * Used in MyBatis mapping. + */ + private void setCreatedAtFromDefinition(@Nullable Long createdAt) { + if (createdAt != null && createdAt > definition.getCreatedAt()) { + setCreatedAt(createdAt); + } + } + + /** + * Used in MyBatis mapping. + */ + private void setCreatedAtFromMetadata(@Nullable Long createdAt) { + if (createdAt != null && createdAt > definition.getCreatedAt()) { + setCreatedAt(createdAt); + } + } + public long getUpdatedAt() { return definition.getUpdatedAt(); } @@ -253,6 +282,24 @@ public class RuleDto { return this; } + /** + * Used in MyBatis mapping. + */ + private void setUpdatedAtFromDefinition(@Nullable Long updatedAt) { + if (updatedAt != null && updatedAt > definition.getUpdatedAt()) { + setUpdatedAt(updatedAt); + } + } + + /** + * Used in MyBatis mapping. + */ + private void setUpdatedAtFromMetadata(@Nullable Long updatedAt) { + if (updatedAt != null && updatedAt > definition.getUpdatedAt()) { + setUpdatedAt(updatedAt); + } + } + public String getOrganizationUuid() { return metadata.getOrganizationUuid(); } @@ -283,21 +330,21 @@ public class RuleDto { } @CheckForNull - public Date getNoteCreatedAt() { + public Long getNoteCreatedAt() { return metadata.getNoteCreatedAt(); } - public RuleDto setNoteCreatedAt(@Nullable Date noteCreatedAt) { + public RuleDto setNoteCreatedAt(@Nullable Long noteCreatedAt) { metadata.setNoteCreatedAt(noteCreatedAt); return this; } @CheckForNull - public Date getNoteUpdatedAt() { + public Long getNoteUpdatedAt() { return metadata.getNoteUpdatedAt(); } - public RuleDto setNoteUpdatedAt(@Nullable Date noteUpdatedAt) { + public RuleDto setNoteUpdatedAt(@Nullable Long noteUpdatedAt) { metadata.setNoteUpdatedAt(noteUpdatedAt); return this; } @@ -336,18 +383,13 @@ public class RuleDto { return metadata.getTags(); } + /** + * Used in MyBatis mapping. + */ private void setTagsField(String s) { metadata.setTagsField(s); } - public Set<String> getSystemTags() { - return definition.getSystemTags(); - } - - private void setSystemTagsField(String s) { - definition.setSystemTagsField(s); - } - public RuleDto setTags(Set<String> tags) { this.metadata.setTags(tags); return this; diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleMapper.java index b9c20bfdf54..f753a624f80 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleMapper.java @@ -27,34 +27,38 @@ import org.sonar.api.rules.RuleQuery; public interface RuleMapper { - List<RuleDto> selectAll(); + List<RuleDto> selectAll(@Param("organizationUuid") String organizationUuid); List<RuleDefinitionDto> selectAllDefinitions(); void selectEnabled(ResultHandler resultHandler); - RuleDto selectById(long id); + RuleDto selectById(@Param("organizationUuid") String organizationUuid, @Param("id") long id); RuleDefinitionDto selectDefinitionById(long id); - List<RuleDto> selectByIds(@Param("ids") List<Integer> ids); + List<RuleDto> selectByIds(@Param("organizationUuid") String organizationUuid, @Param("ids") List<Integer> ids); List<RuleDefinitionDto> selectDefinitionByIds(@Param("ids") List<Integer> ids); - RuleDto selectByKey(RuleKey ruleKey); + RuleDto selectByKey(@Param("organizationUuid") String organizationUuid, @Param("ruleKey") RuleKey ruleKey); RuleDefinitionDto selectDefinitionByKey(RuleKey ruleKey); - List<RuleDto> selectByKeys(@Param("ruleKeys") List<RuleKey> keys); + List<RuleDto> selectByKeys(@Param("organizationUuid") String organizationUuid, @Param("ruleKeys") List<RuleKey> keys); List<RuleDefinitionDto> selectDefinitionByKeys(@Param("ruleKeys") List<RuleKey> keys); - List<RuleDto> selectByQuery(@Param("query") RuleQuery ruleQuery); + List<RuleDto> selectByQuery(@Param("organizationUuid") String organizationUuid, @Param("query") RuleQuery ruleQuery); - void insert(RuleDefinitionDto ruleDefinitionDto); + void insertDefinition(RuleDefinitionDto ruleDefinitionDto); void updateDefinition(RuleDefinitionDto ruleDefinitionDto); + int countMetadata(RuleMetadataDto ruleMetadataDto); + + void insertMetadata(RuleMetadataDto ruleMetadataDto); + void updateMetadata(RuleMetadataDto ruleMetadataDto); List<RuleParamDto> selectParamsByRuleIds(@Param("ruleIds") List<Integer> ruleIds); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleMetadataDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleMetadataDto.java index 3ce1e937f04..594611079fc 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleMetadataDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleMetadataDto.java @@ -20,7 +20,6 @@ package org.sonar.db.rule; import java.util.Arrays; -import java.util.Date; import java.util.HashSet; import java.util.Set; import java.util.TreeSet; @@ -35,12 +34,13 @@ public class RuleMetadataDto { private String organizationUuid; private String noteData; private String noteUserLogin; - private Date noteCreatedAt; - private Date noteUpdatedAt; + private Long noteCreatedAt; + private Long noteUpdatedAt; private String remediationFunction; private String remediationGapMultiplier; private String remediationBaseEffort; private String tags; + private long createdAt; private long updatedAt; public int getRuleId() { @@ -82,21 +82,21 @@ public class RuleMetadataDto { } @CheckForNull - public Date getNoteCreatedAt() { + public Long getNoteCreatedAt() { return noteCreatedAt; } - public RuleMetadataDto setNoteCreatedAt(@Nullable Date noteCreatedAt) { + public RuleMetadataDto setNoteCreatedAt(@Nullable Long noteCreatedAt) { this.noteCreatedAt = noteCreatedAt; return this; } @CheckForNull - public Date getNoteUpdatedAt() { + public Long getNoteUpdatedAt() { return noteUpdatedAt; } - public RuleMetadataDto setNoteUpdatedAt(@Nullable Date noteUpdatedAt) { + public RuleMetadataDto setNoteUpdatedAt(@Nullable Long noteUpdatedAt) { this.noteUpdatedAt = noteUpdatedAt; return this; } @@ -150,6 +150,15 @@ public class RuleMetadataDto { tags = s; } + public long getCreatedAt() { + return createdAt; + } + + public RuleMetadataDto setCreatedAt(long createdAt) { + this.createdAt = createdAt; + return this; + } + public long getUpdatedAt() { return updatedAt; } @@ -172,6 +181,7 @@ public class RuleMetadataDto { ", remediationGapMultiplier='" + remediationGapMultiplier + '\'' + ", remediationBaseEffort='" + remediationBaseEffort + '\'' + ", tags='" + tags + '\'' + + ", createdAt=" + createdAt + ", updatedAt=" + updatedAt + '}'; } diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/rule/RuleMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/rule/RuleMapper.xml index 9cabba05d38..487a9837300 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/rule/RuleMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/rule/RuleMapper.xml @@ -22,57 +22,73 @@ r.gap_description as "gapDescription", r.system_tags as "systemTagsField", r.rule_type as "type", + </sql> + + <sql id="selectRuleTableColumns"> + <include refid="selectDefinitionColumns"/> r.created_at as "createdAt", r.updated_at as "updatedAt" </sql> - <sql id="selectRuleColumns"> - <include refid="selectDefinitionColumns"/>, - r.note_data as "noteData", - r.note_user_login as "noteUserLogin", - r.note_created_at as "noteCreatedAt", - r.note_updated_at as "noteUpdatedAt", - r.remediation_function as "remediationFunction", - r.remediation_gap_mult as "remediationGapMultiplier", - r.remediation_base_effort as "remediationBaseEffort", - r.tags as "tagsField" + <sql id="selectJoinedTablesColumns"> + <include refid="selectDefinitionColumns"/> + r.created_at as "createdAtFromDefinition", + r.updated_at as "updatedAtFromDefinition", + rm.note_data as "noteData", + rm.note_user_login as "noteUserLogin", + rm.note_created_at as "noteCreatedAt", + rm.note_updated_at as "noteUpdatedAt", + rm.remediation_function as "remediationFunction", + rm.remediation_gap_mult as "remediationGapMultiplier", + rm.remediation_base_effort as "remediationBaseEffort", + rm.tags as "tagsField", + rm.created_at as "createdAtFromMetadata", + rm.updated_at as "updatedAtFromMetadata" + </sql> + + <sql id="outerJoinRulesMetadata"> + left outer join rules_metadata rm on + rm.rule_id = r.id + and rm.organization_uuid = #{organizationUuid,jdbcType=VARCHAR} </sql> <select id="selectAll" resultType="Rule"> select - <include refid="selectRuleColumns"/> + <include refid="selectJoinedTablesColumns"/> from rules r + <include refid="outerJoinRulesMetadata"/> </select> <select id="selectAllDefinitions" resultType="org.sonar.db.rule.RuleDefinitionDto"> select - <include refid="selectDefinitionColumns"/> + <include refid="selectRuleTableColumns"/> from rules r </select> <select id="selectEnabled" resultType="org.sonar.db.rule.RuleDefinitionDto"> select - <include refid="selectDefinitionColumns"/> + <include refid="selectRuleTableColumns"/> from rules r where r.status != 'REMOVED' </select> - <select id="selectById" parameterType="Long" resultType="Rule"> + <select id="selectById" parameterType="map" resultType="Rule"> select - <include refid="selectRuleColumns"/> + <include refid="selectJoinedTablesColumns"/> from rules r + <include refid="outerJoinRulesMetadata"/> where r.id=#{id,jdbcType=INTEGER} </select> <select id="selectDefinitionById" parameterType="Long" resultType="org.sonar.db.rule.RuleDefinitionDto"> select - <include refid="selectDefinitionColumns"/> + <include refid="selectRuleTableColumns"/> from rules r where @@ -81,9 +97,10 @@ <select id="selectByIds" parameterType="map" resultType="Rule"> select - <include refid="selectRuleColumns"/> + <include refid="selectJoinedTablesColumns"/> from rules r + <include refid="outerJoinRulesMetadata"/> where <foreach collection="ids" index="index" item="id" open="" separator=" or " close=""> r.id=#{id,jdbcType=INTEGER} @@ -92,7 +109,7 @@ <select id="selectDefinitionByIds" parameterType="map" resultType="org.sonar.db.rule.RuleDefinitionDto"> select - <include refid="selectDefinitionColumns"/> + <include refid="selectRuleTableColumns"/> from rules r where @@ -103,17 +120,18 @@ <select id="selectByKey" parameterType="map" resultType="Rule"> select - <include refid="selectRuleColumns"/> + <include refid="selectJoinedTablesColumns"/> from rules r + <include refid="outerJoinRulesMetadata"/> where - r.plugin_name=#{repository,jdbcType=VARCHAR} - and r.plugin_rule_key=#{rule,jdbcType=VARCHAR} + r.plugin_name=#{ruleKey.repository,jdbcType=VARCHAR} + and r.plugin_rule_key=#{ruleKey.rule,jdbcType=VARCHAR} </select> <select id="selectDefinitionByKey" parameterType="map" resultType="org.sonar.db.rule.RuleDefinitionDto"> select - <include refid="selectDefinitionColumns"/> + <include refid="selectRuleTableColumns"/> from rules r where @@ -123,9 +141,10 @@ <select id="selectByKeys" parameterType="map" resultType="Rule"> select - <include refid="selectRuleColumns"/> + <include refid="selectJoinedTablesColumns"/> from rules r + <include refid="outerJoinRulesMetadata"/> where <foreach collection="ruleKeys" index="index" item="ruleKey" open="" separator=" or " close=""> (r.plugin_name=#{ruleKey.repository,jdbcType=VARCHAR} and r.plugin_rule_key=#{ruleKey.rule,jdbcType=VARCHAR}) @@ -134,7 +153,7 @@ <select id="selectDefinitionByKeys" parameterType="map" resultType="org.sonar.db.rule.RuleDefinitionDto"> select - <include refid="selectDefinitionColumns"/> + <include refid="selectRuleTableColumns"/> from rules r where @@ -145,9 +164,10 @@ <select id="selectByQuery" parameterType="map" resultType="Rule"> select - <include refid="selectRuleColumns"/> + <include refid="selectJoinedTablesColumns"/> from rules r + <include refid="outerJoinRulesMetadata"/> where r.status != 'REMOVED' <if test="query.repositoryKey!=null"> @@ -163,7 +183,7 @@ r.updated_at desc </select> - <insert id="insert" parameterType="org.sonar.db.rule.RuleDefinitionDto" keyColumn="id" useGeneratedKeys="true" keyProperty="id"> + <insert id="insertDefinition" parameterType="org.sonar.db.rule.RuleDefinitionDto" keyColumn="id" useGeneratedKeys="true" keyProperty="id"> insert into rules ( plugin_rule_key, plugin_name, @@ -232,19 +252,61 @@ id=#{id,jdbcType=INTEGER} </update> + <select id="countMetadata" parameterType="org.sonar.db.rule.RuleMetadataDto" resultType="int"> + select + count(1) + from + rules_metadata rm + where + rm.rule_id=#{ruleId,jdbcType=INTEGER} + and rm.organization_uuid=#{organizationUuid,jdbcType=VARCHAR} + </select> + + <insert id="insertMetadata" parameterType="org.sonar.db.rule.RuleMetadataDto"> + insert into rules_metadata ( + rule_id, + organization_uuid, + note_data, + note_user_login, + note_created_at, + note_updated_at, + remediation_function, + remediation_gap_mult, + remediation_base_effort, + tags, + created_at, + updated_at + ) + values ( + #{ruleId,jdbcType=INTEGER}, + #{organizationUuid,jdbcType=VARCHAR}, + #{noteData,jdbcType=CLOB}, + #{noteUserLogin,jdbcType=VARCHAR}, + #{noteCreatedAt,jdbcType=BIGINT}, + #{noteUpdatedAt,jdbcType=BIGINT}, + #{remediationFunction,jdbcType=VARCHAR}, + #{remediationGapMultiplier,jdbcType=VARCHAR}, + #{remediationBaseEffort,jdbcType=VARCHAR}, + #{tagsField,jdbcType=VARCHAR}, + #{createdAt,jdbcType=BIGINT}, + #{updatedAt,jdbcType=BIGINT} + ) + </insert> + <update id="updateMetadata" parameterType="org.sonar.db.rule.RuleMetadataDto"> - update rules set + update rules_metadata set note_data=#{noteData,jdbcType=CLOB}, note_user_login=#{noteUserLogin,jdbcType=VARCHAR}, - note_created_at=#{noteCreatedAt,jdbcType=TIMESTAMP}, - note_updated_at=#{noteUpdatedAt,jdbcType=TIMESTAMP}, + note_created_at=#{noteCreatedAt,jdbcType=BIGINT}, + note_updated_at=#{noteUpdatedAt,jdbcType=BIGINT}, remediation_function=#{remediationFunction,jdbcType=VARCHAR}, remediation_gap_mult=#{remediationGapMultiplier,jdbcType=VARCHAR}, remediation_base_effort=#{remediationBaseEffort,jdbcType=VARCHAR}, tags=#{tagsField,jdbcType=VARCHAR}, updated_at=#{updatedAt,jdbcType=BIGINT} where - id=#{ruleId,jdbcType=INTEGER} + rule_id=#{ruleId,jdbcType=INTEGER} + and organization_uuid=#{organizationUuid,jdbcType=VARCHAR} </update> <delete id="deleteParams" parameterType="Integer"> diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDaoTest.java index 38a85c7bddd..d1d062dd790 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDaoTest.java @@ -69,6 +69,14 @@ public class RuleDaoTest { } @Test + public void selectByKey_populates_organizationUuid_even_when_organization_has_no_metadata() { + dbTester.prepareDbUnit(getClass(), "shared.xml"); + + assertThat(underTest.selectByKey(dbTester.getSession(), ORGANIZATION_UUID, RuleKey.of("java", "S001")).get().getOrganizationUuid()) + .isEqualTo(ORGANIZATION_UUID); + } + + @Test public void selectDefinitionByKey() { dbTester.prepareDbUnit(getClass(), "shared.xml"); @@ -91,6 +99,15 @@ public class RuleDaoTest { } @Test + public void selectById_populates_organizationUuid_even_when_organization_has_no_metadata() { + dbTester.prepareDbUnit(getClass(), "shared.xml"); + String organizationUuid = "org-1"; + + assertThat(underTest.selectById(1l, organizationUuid, dbTester.getSession()).get().getOrganizationUuid()) + .isEqualTo(organizationUuid); + } + + @Test public void selectDefinitionById() { dbTester.prepareDbUnit(getClass(), "shared.xml"); @@ -103,8 +120,8 @@ public class RuleDaoTest { @Test public void selectByIds() { dbTester.prepareDbUnit(getClass(), "shared.xml"); - String organizationUuid = "org-1"; + assertThat(underTest.selectByIds(dbTester.getSession(), organizationUuid, asList(1))).hasSize(1); assertThat(underTest.selectByIds(dbTester.getSession(), organizationUuid, asList(1, 2))).hasSize(2); assertThat(underTest.selectByIds(dbTester.getSession(), organizationUuid, asList(1, 2, 3))).hasSize(2); @@ -113,6 +130,16 @@ public class RuleDaoTest { } @Test + public void selectByIds_populates_organizationUuid_even_when_organization_has_no_metadata() { + dbTester.prepareDbUnit(getClass(), "shared.xml"); + String organizationUuid = "org-1"; + + assertThat(underTest.selectByIds(dbTester.getSession(), organizationUuid, asList(1, 2))) + .extracting(RuleDto::getOrganizationUuid) + .containsExactly(organizationUuid, organizationUuid); + } + + @Test public void selectDefinitionByIds() { dbTester.prepareDbUnit(getClass(), "shared.xml"); @@ -127,7 +154,7 @@ public class RuleDaoTest { public void selectOrFailByKey() { dbTester.prepareDbUnit(getClass(), "shared.xml"); - RuleDefinitionDto rule = underTest.selectOrFailDefinitionByKey(dbTester.getSession(), RuleKey.of("java", "S001")); + RuleDto rule = underTest.selectOrFailByKey(dbTester.getSession(), "org-1", RuleKey.of("java", "S001")); assertThat(rule.getId()).isEqualTo(1); } @@ -142,6 +169,15 @@ public class RuleDaoTest { } @Test + public void selectOrFailByKey_populates_organizationUuid_even_when_organization_has_no_metadata() { + dbTester.prepareDbUnit(getClass(), "shared.xml"); + String organizationUuid = "org-1"; + + assertThat(underTest.selectOrFailByKey(dbTester.getSession(), organizationUuid, RuleKey.of("java", "S001")).getOrganizationUuid()) + .isEqualTo(organizationUuid); + } + + @Test public void selectOrFailDefinitionByKey_fails_if_rule_not_found() { dbTester.prepareDbUnit(getClass(), "shared.xml"); @@ -165,6 +201,16 @@ public class RuleDaoTest { } @Test + public void selectByKeys_populates_organizationUuid_even_when_organization_has_no_metadata() { + dbTester.prepareDbUnit(getClass(), "shared.xml"); + String organizationUuid = "org-1"; + + assertThat(underTest.selectByKeys(dbTester.getSession(), organizationUuid, asList(RuleKey.of("java", "S001"), RuleKey.of("java", "OTHER")))) + .extracting(RuleDto::getOrganizationUuid) + .containsExactly(organizationUuid); + } + + @Test public void selectDefinitionByKeys() { dbTester.prepareDbUnit(getClass(), "shared.xml"); @@ -180,9 +226,19 @@ public class RuleDaoTest { public void selectAll() { dbTester.prepareDbUnit(getClass(), "shared.xml"); - List<RuleDto> ruleDtos = underTest.selectAll(dbTester.getSession(), "org-1"); + assertThat(underTest.selectAll(dbTester.getSession(), "org-1")) + .extracting(RuleDto::getId) + .containsOnly(1, 2, 10); + } - assertThat(ruleDtos).extracting("id").containsOnly(1, 2, 10); + @Test + public void selectAll_populates_organizationUuid_even_when_organization_has_no_metadata() { + dbTester.prepareDbUnit(getClass(), "shared.xml"); + String organizationUuid = "org-1"; + + assertThat(underTest.selectAll(dbTester.getSession(), organizationUuid)) + .extracting(RuleDto::getOrganizationUuid) + .containsExactly(organizationUuid, organizationUuid, organizationUuid); } @Test @@ -230,6 +286,16 @@ public class RuleDaoTest { } @Test + public void select_by_query_populates_organizationUuid_even_when_organization_has_no_metadata() { + dbTester.prepareDbUnit(getClass(), "shared.xml"); + String organizationUuid = "org-1"; + + assertThat(underTest.selectByQuery(dbTester.getSession(), organizationUuid, RuleQuery.create())) + .extracting(RuleDto::getOrganizationUuid) + .containsExactly(organizationUuid, organizationUuid); + } + + @Test public void insert() throws Exception { RuleDefinitionDto newRule = new RuleDefinitionDto() .setRuleKey("NewRuleKey") @@ -249,8 +315,8 @@ public class RuleDaoTest { .setGapDescription("squid.S115.effortToFix") .setSystemTags(newHashSet("systag1", "systag2")) .setType(RuleType.BUG) - .setCreatedAt(1500000000000L) - .setUpdatedAt(2000000000000L); + .setCreatedAt(1_500_000_000_000L) + .setUpdatedAt(2_000_000_000_000L); underTest.insert(dbTester.getSession(), newRule); dbTester.getSession().commit(); @@ -273,8 +339,8 @@ public class RuleDaoTest { assertThat(ruleDto.getGapDescription()).isEqualTo("squid.S115.effortToFix"); assertThat(ruleDto.getSystemTags()).containsOnly("systag1", "systag2"); assertThat(ruleDto.getType()).isEqualTo(RuleType.BUG.getDbConstant()); - assertThat(ruleDto.getCreatedAt()).isEqualTo(1500000000000L); - assertThat(ruleDto.getUpdatedAt()).isEqualTo(2000000000000L); + assertThat(ruleDto.getCreatedAt()).isEqualTo(1_500_000_000_000L); + assertThat(ruleDto.getUpdatedAt()).isEqualTo(2_000_000_000_000L); } @Test @@ -300,7 +366,7 @@ public class RuleDaoTest { .setGapDescription("squid.S115.effortToFix") .setSystemTags(newHashSet("systag1", "systag2")) .setType(RuleType.BUG) - .setUpdatedAt(2000000000000L); + .setUpdatedAt(2_000_000_000_000L); underTest.update(dbTester.getSession(), ruleToUpdate); dbTester.getSession().commit(); @@ -323,27 +389,28 @@ public class RuleDaoTest { assertThat(ruleDto.getGapDescription()).isEqualTo("squid.S115.effortToFix"); assertThat(ruleDto.getSystemTags()).containsOnly("systag1", "systag2"); assertThat(ruleDto.getType()).isEqualTo(RuleType.BUG.getDbConstant()); - assertThat(ruleDto.getCreatedAt()).isEqualTo(1500000000000L); - assertThat(ruleDto.getUpdatedAt()).isEqualTo(2000000000000L); + assertThat(ruleDto.getCreatedAt()).isEqualTo(1_500_000_000_000L); + assertThat(ruleDto.getUpdatedAt()).isEqualTo(2_000_000_000_000L); } @Test - public void update_RuleMetadataDto() { + public void update_RuleMetadataDto_inserts_row_in_RULE_METADATA_if_not_exists_yet() { dbTester.prepareDbUnit(getClass(), "update.xml"); - String organizationUuid = "org-1"; + RuleMetadataDto ruleToUpdate = new RuleMetadataDto() .setRuleId(1) .setOrganizationUuid(organizationUuid) .setNoteData("My note") .setNoteUserLogin("admin") - .setNoteCreatedAt(DateUtils.parseDate("2013-12-19")) - .setNoteUpdatedAt(DateUtils.parseDate("2013-12-20")) + .setNoteCreatedAt(DateUtils.parseDate("2013-12-19").getTime()) + .setNoteUpdatedAt(DateUtils.parseDate("2013-12-20").getTime()) .setRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString()) .setRemediationGapMultiplier("1h") .setRemediationBaseEffort("5min") .setTags(newHashSet("tag1", "tag2")) - .setUpdatedAt(2000000000000L); + .setCreatedAt(3_500_000_000_000L) + .setUpdatedAt(4_000_000_000_000L); underTest.update(dbTester.getSession(), ruleToUpdate); dbTester.getSession().commit(); @@ -374,8 +441,97 @@ public class RuleDaoTest { assertThat(ruleDto.getTags()).containsOnly("tag1", "tag2"); assertThat(ruleDto.getSystemTags()).isEmpty(); assertThat(ruleDto.getType()).isEqualTo(0); - assertThat(ruleDto.getCreatedAt()).isEqualTo(1500000000000L); - assertThat(ruleDto.getUpdatedAt()).isEqualTo(2000000000000L); + assertThat(ruleDto.getCreatedAt()).isEqualTo(3_500_000_000_000L); + assertThat(ruleDto.getUpdatedAt()).isEqualTo(4_000_000_000_000L); + } + + @Test + public void update_RuleMetadataDto_updates_row_in_RULE_METADATA_if_already_exists() { + dbTester.prepareDbUnit(getClass(), "update.xml"); + String organizationUuid = "org-1"; + RuleMetadataDto metadataV1 = new RuleMetadataDto() + .setRuleId(1) + .setOrganizationUuid(organizationUuid) + .setCreatedAt(3_500_000_000_000L) + .setUpdatedAt(4_000_000_000_000L); + RuleMetadataDto metadataV2 = new RuleMetadataDto() + .setRuleId(1) + .setOrganizationUuid(organizationUuid) + .setNoteData("My note") + .setNoteUserLogin("admin") + .setNoteCreatedAt(DateUtils.parseDate("2013-12-19").getTime()) + .setNoteUpdatedAt(DateUtils.parseDate("2013-12-20").getTime()) + .setRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString()) + .setRemediationGapMultiplier("1h") + .setRemediationBaseEffort("5min") + .setTags(newHashSet("tag1", "tag2")) + .setCreatedAt(6_500_000_000_000L) + .setUpdatedAt(7_000_000_000_000L); + + underTest.update(dbTester.getSession(), metadataV1); + dbTester.commit(); + + assertThat(dbTester.countRowsOfTable("RULES_METADATA")).isEqualTo(1); + RuleDto ruleDto = underTest.selectOrFailByKey(dbTester.getSession(), organizationUuid, RuleKey.of("checkstyle", "AvoidNull")); + assertThat(ruleDto.getName()).isEqualTo("Avoid Null"); + assertThat(ruleDto.getDescription()).isEqualTo("Should avoid NULL"); + assertThat(ruleDto.getDescriptionFormat()).isNull(); + assertThat(ruleDto.getStatus()).isEqualTo(RuleStatus.READY); + assertThat(ruleDto.getRuleKey()).isEqualTo("AvoidNull"); + assertThat(ruleDto.getRepositoryKey()).isEqualTo("checkstyle"); + assertThat(ruleDto.getConfigKey()).isEqualTo("AvoidNull"); + assertThat(ruleDto.getSeverity()).isEqualTo(2); + assertThat(ruleDto.getLanguage()).isEqualTo("golo"); + assertThat(ruleDto.isTemplate()).isFalse(); + assertThat(ruleDto.getTemplateId()).isNull(); + assertThat(ruleDto.getNoteData()).isNull(); + assertThat(ruleDto.getNoteUserLogin()).isNull(); + assertThat(ruleDto.getNoteCreatedAt()).isNull(); + assertThat(ruleDto.getNoteUpdatedAt()).isNull(); + assertThat(ruleDto.getRemediationFunction()).isNull(); + assertThat(ruleDto.getDefaultRemediationFunction()).isNull(); + assertThat(ruleDto.getRemediationGapMultiplier()).isNull(); + assertThat(ruleDto.getDefaultRemediationGapMultiplier()).isNull(); + assertThat(ruleDto.getRemediationBaseEffort()).isNull(); + assertThat(ruleDto.getDefaultRemediationBaseEffort()).isNull(); + assertThat(ruleDto.getGapDescription()).isNull(); + assertThat(ruleDto.getTags()).isEmpty(); + assertThat(ruleDto.getSystemTags()).isEmpty(); + assertThat(ruleDto.getType()).isEqualTo(0); + assertThat(ruleDto.getCreatedAt()).isEqualTo(3_500_000_000_000L); + assertThat(ruleDto.getUpdatedAt()).isEqualTo(4_000_000_000_000L); + + underTest.update(dbTester.getSession(), metadataV2); + dbTester.commit(); + + ruleDto = underTest.selectOrFailByKey(dbTester.getSession(), organizationUuid, RuleKey.of("checkstyle", "AvoidNull")); + assertThat(ruleDto.getName()).isEqualTo("Avoid Null"); + assertThat(ruleDto.getDescription()).isEqualTo("Should avoid NULL"); + assertThat(ruleDto.getDescriptionFormat()).isNull(); + assertThat(ruleDto.getStatus()).isEqualTo(RuleStatus.READY); + assertThat(ruleDto.getRuleKey()).isEqualTo("AvoidNull"); + assertThat(ruleDto.getRepositoryKey()).isEqualTo("checkstyle"); + assertThat(ruleDto.getConfigKey()).isEqualTo("AvoidNull"); + assertThat(ruleDto.getSeverity()).isEqualTo(2); + assertThat(ruleDto.getLanguage()).isEqualTo("golo"); + assertThat(ruleDto.isTemplate()).isFalse(); + assertThat(ruleDto.getTemplateId()).isNull(); + assertThat(ruleDto.getNoteData()).isEqualTo("My note"); + assertThat(ruleDto.getNoteUserLogin()).isEqualTo("admin"); + assertThat(ruleDto.getNoteCreatedAt()).isNotNull(); + assertThat(ruleDto.getNoteUpdatedAt()).isNotNull(); + assertThat(ruleDto.getRemediationFunction()).isEqualTo("LINEAR"); + assertThat(ruleDto.getDefaultRemediationFunction()).isNull(); + assertThat(ruleDto.getRemediationGapMultiplier()).isEqualTo("1h"); + assertThat(ruleDto.getDefaultRemediationGapMultiplier()).isNull(); + assertThat(ruleDto.getRemediationBaseEffort()).isEqualTo("5min"); + assertThat(ruleDto.getDefaultRemediationBaseEffort()).isNull(); + assertThat(ruleDto.getGapDescription()).isNull(); + assertThat(ruleDto.getTags()).containsOnly("tag1", "tag2"); + assertThat(ruleDto.getSystemTags()).isEmpty(); + assertThat(ruleDto.getType()).isEqualTo(0); + assertThat(ruleDto.getCreatedAt()).isEqualTo(3_500_000_000_000L); + assertThat(ruleDto.getUpdatedAt()).isEqualTo(7_000_000_000_000L); } @Test diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleTesting.java b/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleTesting.java index a657a2edffa..c56015f0adf 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleTesting.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleTesting.java @@ -100,7 +100,7 @@ public class RuleTesting { return newDto(ruleKey, null); } - private static RuleDto newDto(RuleKey ruleKey, @Nullable OrganizationDto organization) { + public static RuleDto newDto(RuleKey ruleKey, @Nullable OrganizationDto organization) { RuleDto res = new RuleDto() .setRuleKey(ruleKey.rule()) .setRepositoryKey(ruleKey.repository()) |