aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-db-dao
diff options
context:
space:
mode:
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>2017-03-22 11:49:05 +0100
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>2017-03-23 17:54:56 +0100
commit4b25bc908dd178cd656002d28851e0b4ec0fdb95 (patch)
tree7333cb447297829344de9af5369dc7bcb299a6cf /server/sonar-db-dao
parentf63f13424bb24c5b3e825e12b0f9b0cea125d4f8 (diff)
downloadsonarqube-4b25bc908dd178cd656002d28851e0b4ec0fdb95.tar.gz
sonarqube-4b25bc908dd178cd656002d28851e0b4ec0fdb95.zip
SONAR-8867 read and write into table RULES_METADATA
Diffstat (limited to 'server/sonar-db-dao')
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDao.java42
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java68
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleMapper.java18
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleMetadataDto.java24
-rw-r--r--server/sonar-db-dao/src/main/resources/org/sonar/db/rule/RuleMapper.xml122
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDaoTest.java192
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleTesting.java2
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())