diff options
author | Sébastien Lesaint <sebastien.lesaint@sonarsource.com> | 2016-09-02 14:00:58 +0200 |
---|---|---|
committer | Sébastien Lesaint <sebastien.lesaint@sonarsource.com> | 2016-09-09 09:11:42 +0200 |
commit | 526583323c8dd7f5ea174757726218cec784848a (patch) | |
tree | 269c1d81f9cd5358f6c27d609d194e091b795fd8 /sonar-db | |
parent | b8c0becf8da211ed31d728ea38eb9978223caa2a (diff) | |
download | sonarqube-526583323c8dd7f5ea174757726218cec784848a.tar.gz sonarqube-526583323c8dd7f5ea174757726218cec784848a.zip |
SONAR-7676 PropertiesDao supports IS_EMPTY, TEXT_VALUE and CLOB_VALUE
Diffstat (limited to 'sonar-db')
44 files changed, 1553 insertions, 792 deletions
diff --git a/sonar-db/src/main/java/org/sonar/core/properties/PropertiesDao.java b/sonar-db/src/main/java/org/sonar/core/properties/PropertiesDao.java index 2c97e6f2561..2c64a11ec9c 100644 --- a/sonar-db/src/main/java/org/sonar/core/properties/PropertiesDao.java +++ b/sonar-db/src/main/java/org/sonar/core/properties/PropertiesDao.java @@ -19,6 +19,7 @@ */ package org.sonar.core.properties; +import org.sonar.api.utils.System2; import org.sonar.db.MyBatis; /** @@ -29,11 +30,11 @@ import org.sonar.db.MyBatis; @Deprecated public class PropertiesDao extends org.sonar.db.property.PropertiesDao { - public PropertiesDao(MyBatis mybatis) { - super(mybatis); + public PropertiesDao(MyBatis mybatis, System2 system2) { + super(mybatis, system2); } public void setProperty(PropertyDto property) { - super.insertProperty(property); + super.saveProperty(property); } } diff --git a/sonar-db/src/main/java/org/sonar/db/MyBatis.java b/sonar-db/src/main/java/org/sonar/db/MyBatis.java index c9df79927b7..e2d37996d3c 100644 --- a/sonar-db/src/main/java/org/sonar/db/MyBatis.java +++ b/sonar-db/src/main/java/org/sonar/db/MyBatis.java @@ -95,7 +95,7 @@ import org.sonar.db.permission.template.PermissionTemplateUserDto; import org.sonar.db.property.InternalPropertiesMapper; import org.sonar.db.property.InternalPropertyDto; import org.sonar.db.property.PropertiesMapper; -import org.sonar.db.property.PropertyDto; +import org.sonar.db.property.ScrapPropertyDto; import org.sonar.db.purge.IdUuidPair; import org.sonar.db.purge.PurgeMapper; import org.sonar.db.purge.PurgeableAnalysisDto; @@ -176,7 +176,7 @@ public class MyBatis { confBuilder.loadAlias("MeasureFilter", MeasureFilterDto.class); confBuilder.loadAlias("MeasureFilterFavourite", MeasureFilterFavouriteDto.class); confBuilder.loadAlias("NotificationQueue", NotificationQueueDto.class); - confBuilder.loadAlias("Property", PropertyDto.class); + confBuilder.loadAlias("ScrapProperty", ScrapPropertyDto.class); confBuilder.loadAlias("InternalProperty", InternalPropertyDto.class); confBuilder.loadAlias("PurgeableAnalysis", PurgeableAnalysisDto.class); confBuilder.loadAlias("QualityGate", QualityGateDto.class); diff --git a/sonar-db/src/main/java/org/sonar/db/property/PropertiesDao.java b/sonar-db/src/main/java/org/sonar/db/property/PropertiesDao.java index 86d8c594e96..7af84391331 100644 --- a/sonar-db/src/main/java/org/sonar/db/property/PropertiesDao.java +++ b/sonar-db/src/main/java/org/sonar/db/property/PropertiesDao.java @@ -30,8 +30,8 @@ import java.util.Map; import java.util.Set; import javax.annotation.CheckForNull; import javax.annotation.Nullable; -import org.apache.commons.lang.StringUtils; import org.sonar.api.resources.Scopes; +import org.sonar.api.utils.System2; import org.sonar.db.Dao; import org.sonar.db.DatabaseUtils; import org.sonar.db.DbSession; @@ -43,10 +43,14 @@ import static org.sonar.db.DatabaseUtils.executeLargeInputs; public class PropertiesDao implements Dao { private static final String NOTIFICATION_PREFIX = "notification."; - private MyBatis mybatis; + private static final int VARCHAR_MAXSIZE = 4000; - public PropertiesDao(MyBatis mybatis) { + private final MyBatis mybatis; + private final System2 system2; + + public PropertiesDao(MyBatis mybatis, System2 system2) { this.mybatis = mybatis; + this.system2 = system2; } /** @@ -130,15 +134,15 @@ public class PropertiesDao implements Dao { } @CheckForNull - public PropertyDto selectProjectProperty(long resourceId, String propertyKey) { + public PropertyDto selectProjectProperty(long componentId, String propertyKey) { try (DbSession session = mybatis.openSession(false)) { - return selectProjectProperty(session, resourceId, propertyKey); + return selectProjectProperty(session, componentId, propertyKey); } } @CheckForNull - public PropertyDto selectProjectProperty(DbSession dbSession, long resourceId, String propertyKey) { - return getMapper(dbSession).selectByKey(new PropertyDto().setKey(propertyKey).setResourceId(resourceId)); + public PropertyDto selectProjectProperty(DbSession dbSession, long componentId, String propertyKey) { + return getMapper(dbSession).selectByKey(new PropertyDto().setKey(propertyKey).setResourceId(componentId)); } public List<PropertyDto> selectByQuery(PropertyQuery query, DbSession session) { @@ -162,24 +166,57 @@ public class PropertiesDao implements Dao { return executeLargeInputs(keys, partitionKeys -> getMapper(session).selectByKeys(partitionKeys, componentId)); } - public void insertProperty(DbSession session, PropertyDto property) { - PropertiesMapper mapper = getMapper(session); - PropertyDto persistedProperty = mapper.selectByKey(property); - if (persistedProperty != null && !StringUtils.equals(persistedProperty.getValue(), property.getValue())) { - persistedProperty.setValue(property.getValue()); - mapper.update(persistedProperty); - } else if (persistedProperty == null) { - mapper.insert(property); + /** + * Saves the specified property and its value. + * <p> + * If {@link PropertyDto#getValue()} is {@code null} or empty, the properties is persisted as empty. + * </p> + * + * @throws IllegalArgumentException if {@link PropertyDto#getKey()} is {@code null} or empty + */ + public void saveProperty(DbSession session, PropertyDto property) { + save(getMapper(session), property.getKey(), property.getUserId(), property.getResourceId(), property.getValue()); + } + + private void save(PropertiesMapper mapper, + String key, @Nullable Long userId, @Nullable Long componentId, + @Nullable String value) { + checkKey(key); + + long now = system2.now(); + mapper.delete(key, userId, componentId); + if (isEmpty(value)) { + mapper.insertAsEmpty(key, userId, componentId, now); + } else if (mustBeStoredInClob(value)) { + mapper.insertAsClob(key, userId, componentId, value, now); + } else { + mapper.insertAsText(key, userId, componentId, value, now); } } - public void insertProperty(PropertyDto property) { + private static boolean mustBeStoredInClob(String value) { + return value.length() > VARCHAR_MAXSIZE; + } + + private static void checkKey(@Nullable String key) { + checkArgument(!isEmpty(key), "key can't be null nor empty"); + } + + private static boolean isEmpty(@Nullable String str) { + return str == null || str.isEmpty(); + } + + public void saveProperty(PropertyDto property) { try (DbSession session = mybatis.openSession(false)) { - insertProperty(session, property); + saveProperty(session, property); session.commit(); } } + public int delete(DbSession dbSession, PropertyDto dto) { + return getMapper(dbSession).delete(dto.getKey(), dto.getUserId(), dto.getResourceId()); + } + public void deleteById(DbSession dbSession, long id) { getMapper(dbSession).deleteById(id); } @@ -217,23 +254,17 @@ public class PropertiesDao implements Dao { } } - public void insertGlobalProperties(Map<String, String> properties) { + public void saveGlobalProperties(Map<String, String> properties) { try (DbSession session = mybatis.openSession(false)) { PropertiesMapper mapper = getMapper(session); - properties.entrySet().forEach(entry -> delete(mapper, entry)); - properties.entrySet().forEach(entry -> insert(mapper, entry)); + properties.entrySet().forEach(entry -> { + mapper.deleteGlobalProperty(entry.getKey()); + save(mapper, entry.getKey(), null, null, entry.getValue()); + }); session.commit(); } } - private static void delete(PropertiesMapper mapper, Map.Entry<String, String> entry) { - mapper.deleteGlobalProperty(entry.getKey()); - } - - private static void insert(PropertiesMapper mapper, Map.Entry<String, String> entry) { - mapper.insert(new PropertyDto().setKey(entry.getKey()).setValue(entry.getValue())); - } - public void renamePropertyKey(String oldKey, String newKey) { checkArgument(!Strings.isNullOrEmpty(oldKey), "Old property key must not be empty"); checkArgument(!Strings.isNullOrEmpty(newKey), "New property key must not be empty"); diff --git a/sonar-db/src/main/java/org/sonar/db/property/PropertiesMapper.java b/sonar-db/src/main/java/org/sonar/db/property/PropertiesMapper.java index bb58987065d..e438c73c8c9 100644 --- a/sonar-db/src/main/java/org/sonar/db/property/PropertiesMapper.java +++ b/sonar-db/src/main/java/org/sonar/db/property/PropertiesMapper.java @@ -44,18 +44,24 @@ public interface PropertiesMapper { List<PropertyDto> selectDescendantModuleProperties(@Param("moduleUuid") String moduleUuid, @Param(value = "scope") String scope, @Param(value = "excludeDisabled") boolean excludeDisabled); - void update(PropertyDto property); + void insertAsEmpty(@Param("key") String key, @Nullable @Param("userId") Long userId, @Nullable @Param("componentId") Long componentId, + @Param("now") long now); - void insert(PropertyDto property); + void insertAsText(@Param("key") String key, @Nullable @Param("userId") Long userId, @Nullable @Param("componentId") Long componentId, + @Param("value") String value, @Param("now") long now); - void deleteById(long id); + void insertAsClob(@Param("key") String key, @Nullable @Param("userId") Long userId, @Nullable @Param("componentId") Long componentId, + @Param("value") String value, @Param("now") long now); - void deleteProjectProperty(@Param("key") String key, @Param("rId") Long resourceId); + int delete(@Param("key") String key, @Nullable @Param("userId") Long userId, @Nullable @Param("componentId") Long componentId); - void deleteProjectProperties(@Param("key") String key, @Param("value") String value); + int deleteById(long id); - void deleteGlobalProperty(String key); + int deleteProjectProperty(@Param("key") String key, @Param("rId") Long componentId); - void renamePropertyKey(@Param("oldKey") String oldKey, @Param("newKey") String newKey); + int deleteProjectProperties(@Param("key") String key, @Param("value") String value); + int deleteGlobalProperty(@Param("key") String key); + + int renamePropertyKey(@Param("oldKey") String oldKey, @Param("newKey") String newKey); } diff --git a/sonar-db/src/main/java/org/sonar/db/property/PropertyDto.java b/sonar-db/src/main/java/org/sonar/db/property/PropertyDto.java index 404be7e30ad..22f0998b353 100644 --- a/sonar-db/src/main/java/org/sonar/db/property/PropertyDto.java +++ b/sonar-db/src/main/java/org/sonar/db/property/PropertyDto.java @@ -58,7 +58,7 @@ public class PropertyDto { return value; } - public PropertyDto setValue(String value) { + public PropertyDto setValue(@Nullable String value) { this.value = value; return this; } @@ -91,12 +91,11 @@ public class PropertyDto { if (getClass() != obj.getClass()) { return false; } - final PropertyDto other = (PropertyDto) obj; - + PropertyDto other = (PropertyDto) obj; return Objects.equals(this.key, other.key) - && Objects.equals(this.value, other.value) && Objects.equals(this.userId, other.userId) - && Objects.equals(this.resourceId, other.resourceId); + && Objects.equals(this.resourceId, other.resourceId) + && Objects.equals(this.value, other.value); } @Override diff --git a/sonar-db/src/main/java/org/sonar/db/property/ScrapPropertyDto.java b/sonar-db/src/main/java/org/sonar/db/property/ScrapPropertyDto.java new file mode 100644 index 00000000000..ded0ac70549 --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/property/ScrapPropertyDto.java @@ -0,0 +1,43 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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.sonar.db.property; + +import javax.annotation.Nullable; + +public class ScrapPropertyDto extends PropertyDto { + public void setEmpty(boolean flag) { + if (flag) { + setValue(""); + } + } + + public void setTextValue(@Nullable String value) { + if (value != null) { + setValue(value); + } + } + + public void setClobValue(@Nullable String value) { + if (value != null) { + setValue(value); + } + } + +} diff --git a/sonar-db/src/main/resources/org/sonar/db/property/PropertiesMapper.xml b/sonar-db/src/main/resources/org/sonar/db/property/PropertiesMapper.xml index e94a1cc31d1..e3bae5b1baa 100644 --- a/sonar-db/src/main/resources/org/sonar/db/property/PropertiesMapper.xml +++ b/sonar-db/src/main/resources/org/sonar/db/property/PropertiesMapper.xml @@ -4,156 +4,292 @@ <mapper namespace="org.sonar.db.property.PropertiesMapper"> <select id="findUsersForNotification" parameterType="map" resultType="String"> - select u.login - from users u - inner join properties p on p.user_id=u.id - <if test="projectUuid == null"> - where p.prop_key = #{notifKey} and p.text_value LIKE 'true' and p.resource_id is null - </if> - <if test="projectUuid != null"> - inner join projects c on c.id=p.resource_id - where p.prop_key = #{notifKey} AND p.text_value LIKE 'true' - and c.uuid = #{projectUuid} and p.resource_id is not null - </if> + select + u.login + from + users u + inner join properties p on + p.user_id=u.id + <choose> + <when test="projectUuid == null"> + where + p.prop_key = #{notifKey} + and p.text_value = 'true' + and p.resource_id is null + </when> + <otherwise> + inner join projects c on + c.id=p.resource_id + where + p.prop_key = #{notifKey} + and p.text_value = 'true' + and c.uuid = #{projectUuid} + and p.resource_id is not null + </otherwise> + </choose> </select> <select id="findNotificationSubscribers" parameterType="map" resultType="String"> - SELECT U.login - FROM properties P, users U - WHERE P.user_id = U.id AND P.prop_key = #{propKey} AND P.text_value LIKE 'true' - AND ( - P.resource_id is null - <if test="componentKey != null"> - OR P.resource_id in (select id from projects where kee=#{componentKey}) - </if> - ) + select + u.login + from + properties p, + users u + where + p.user_id = u.id + and p.prop_key = #{propKey} + and p.text_value like 'true' + and ( + p.resource_id is null + <if test="componentKey != null"> + or p.resource_id in (select id from projects where kee=#{componentKey}) + </if> + ) </select> - <select id="selectGlobalProperties" resultType="Property"> - select p.id as id, p.prop_key as "key", p.text_value as value, p.resource_id as resourceId, p.user_id as userId - from properties p - where p.resource_id is null and p.user_id is null + <sql id="columnsToScrapPropertyDto"> + p.id as id, + p.prop_key as "key", + p.is_empty as empty, + p.text_value as textValue, + p.clob_value as clobValue, + p.resource_id as resourceId, + p.user_id as userId + </sql> + + <select id="selectGlobalProperties" resultType="ScrapProperty"> + select + <include refid="columnsToScrapPropertyDto"/> + from + properties p + where + p.resource_id is null + and p.user_id is null </select> - <select id="selectProjectProperties" parameterType="String" resultType="Property"> - select p.id as id, p.prop_key as "key", p.text_value as value, p.resource_id as resourceId, p.user_id as userId - from properties p, projects r - where p.resource_id=r.id and p.user_id is null and r.kee=#{resourceKey} + <select id="selectProjectProperties" parameterType="String" resultType="ScrapProperty"> + select + <include refid="columnsToScrapPropertyDto"/> + from + properties p, + projects r + where + p.resource_id=r.id + and p.user_id is null + and r.kee=#{resourceKey} </select> - <select id="selectDescendantModuleProperties" parameterType="String" resultType="Property"> - SELECT prop.id as id, prop.prop_key as "key", prop.text_value as value, prop.resource_id as resourceId, prop.user_id - as userId - FROM properties prop - INNER JOIN (SELECT p.id FROM projects p<include refid="org.sonar.db.component.ComponentMapper.modulesTreeQuery"/>) - modules on modules.id=prop.resource_id - WHERE prop.user_id IS NULL + <select id="selectDescendantModuleProperties" parameterType="String" resultType="ScrapProperty"> + select + <include refid="columnsToScrapPropertyDto"/> + from + properties p + inner join (select p.id from projects p<include refid="org.sonar.db.component.ComponentMapper.modulesTreeQuery"/>) modules + on modules.id=p.resource_id + where + p.user_id is null </select> - <select id="selectByKey" parameterType="map" resultType="Property"> - select p.id as id, p.prop_key as "key", p.text_value as value, p.resource_id as resourceId, p.user_id as userId - from properties p - where p.prop_key=#{key} - <if test="resourceId == null"> - AND p.resource_id is null - </if> - <if test="resourceId != null"> - AND p.resource_id=#{resourceId} - </if> - <if test="userId == null"> - AND p.user_id is null - </if> - <if test="userId != null"> - AND p.user_id=#{userId} - </if> + <select id="selectByKey" parameterType="map" resultType="ScrapProperty"> + select + <include refid="columnsToScrapPropertyDto"/> + from + properties p + where + p.prop_key=#{key} + <if test="resourceId == null"> + and p.resource_id is null + </if> + <if test="resourceId != null"> + and p.resource_id=#{resourceId} + </if> + <if test="userId == null"> + and p.user_id is null + </if> + <if test="userId != null"> + and p.user_id=#{userId} + </if> </select> - <select id="selectByKeys" parameterType="map" resultType="Property"> - SELECT p.id as id, p.prop_key as "key", p.text_value as value, p.resource_id as resourceId, p.user_id as userId - FROM properties p - <where> - AND p.prop_key in - <foreach collection="keys" open="(" close=")" item="key" separator=","> - #{key} - </foreach> + <select id="selectByKeys" parameterType="map" resultType="ScrapProperty"> + select + <include refid="columnsToScrapPropertyDto"/> + from + properties p + where + p.prop_key in + <foreach collection="keys" open="(" close=")" item="key" separator=","> + #{key} + </foreach> <if test="componentId == null"> - AND p.resource_id is null + and p.resource_id is null </if> <if test="componentId != null"> - AND p.resource_id=#{componentId} + and p.resource_id=#{componentId} </if> - AND p.user_id is null - </where> + and p.user_id is null </select> - <select id="selectByKeysAndComponentIds" parameterType="map" resultType="Property"> - SELECT p.id as id, p.prop_key as "key", p.text_value as value, p.resource_id as resourceId, p.user_id as userId - FROM properties p - <where> - AND p.prop_key in - <foreach collection="keys" open="(" close=")" item="key" separator=","> - #{key} - </foreach> - AND p.resource_id in - <foreach collection="componentIds" open="(" close=")" item="componentId" separator=","> - #{componentId} - </foreach> - AND p.user_id is null - </where> + <select id="selectByKeysAndComponentIds" parameterType="map" resultType="ScrapProperty"> + select + <include refid="columnsToScrapPropertyDto"/> + from + properties p + where + p.prop_key in + <foreach collection="keys" open="(" close=")" item="key" separator=","> + #{key} + </foreach> + and p.resource_id in + <foreach collection="componentIds" open="(" close=")" item="componentId" separator=","> + #{componentId} + </foreach> + and p.user_id is null </select> - <select id="selectByQuery" parameterType="map" resultType="Property"> - select p.id as id, p.prop_key as "key", p.text_value as value, p.resource_id as resourceId, p.user_id as userId - from properties p + <select id="selectByQuery" parameterType="map" resultType="ScrapProperty"> + select + <include refid="columnsToScrapPropertyDto"/> + from + properties p <where> <if test="query.key() != null"> - AND p.prop_key=#{query.key} + and p.prop_key=#{query.key} </if> <if test="query.componentId() != null"> - AND p.resource_id=#{query.componentId} + and p.resource_id=#{query.componentId} </if> <if test="query.userId() != null"> - AND p.user_id=#{query.userId} + and p.user_id=#{query.userId} </if> </where> </select> - <update id="update" parameterType="Property"> - update properties set text_value = #{value} where id = #{id} - </update> + <insert id="insertAsEmpty" parameterType="Map" useGeneratedKeys="false"> + insert into properties + ( + prop_key, + resource_id, + user_id, + is_empty, + created_at + ) + values ( + #{key}, + #{componentId}, + #{userId}, + ${_true}, + #{now} + ) + </insert> - <insert id="insert" parameterType="Property" useGeneratedKeys="false"> - INSERT INTO properties (prop_key, resource_id, user_id, text_value) - VALUES (#{key}, #{resourceId}, #{userId}, #{value}) + <insert id="insertAsText" parameterType="Map" useGeneratedKeys="false"> + insert into properties + ( + prop_key, + resource_id, + user_id, + is_empty, + text_value, + created_at + ) + values ( + #{key}, + #{componentId}, + #{userId}, + ${_false}, + #{value}, + #{now} + ) </insert> + <insert id="insertAsClob" parameterType="Map" useGeneratedKeys="false"> + insert into properties + ( + prop_key, + resource_id, + user_id, + is_empty, + clob_value, + created_at + ) + values ( + #{key}, + #{componentId}, + #{userId}, + ${_false}, + #{value}, + #{now} + ) + </insert> + + <delete id="delete" parameterType="map"> + delete from properties + where + prop_key=#{key} + <choose> + <when test="componentId != null && userId != null"> + and resource_id=#{componentId} + and user_id=#{userId} + </when> + <when test="componentId != null"> + and resource_id=#{componentId} + and user_id is null + </when> + <when test="userId != null"> + and resource_id is null + and user_id=#{userId} + </when> + <otherwise> + and resource_id is null + and user_id is null + </otherwise> + </choose> + </delete> + <delete id="deleteById" parameterType="long"> - delete from properties where id=#{id} + delete from properties + where + id=#{id} </delete> <delete id="deleteProjectProperty" parameterType="map"> - delete from properties where prop_key=#{key} and resource_id=#{rId} and user_id is null + delete from properties + where + prop_key=#{key} + and resource_id=#{rId} + and user_id is null </delete> <delete id="deleteProjectProperties" parameterType="map"> - DELETE FROM properties - WHERE - prop_key=#{key} - AND text_value LIKE #{value} - AND resource_id IS NOT NULL - AND user_id IS NULL + delete from properties + where + prop_key=#{key} + and text_value = #{value} + and resource_id is not null + and user_id is null </delete> <delete id="deleteGlobalProperty" parameterType="string"> - delete from properties where prop_key=#{id} and resource_id is null and user_id is null + delete from properties + where + prop_key=#{key} + and resource_id is null + and user_id is null </delete> <delete id="deleteGlobalProperties"> - delete from properties where resource_id is null and user_id is null + delete from properties + where + resource_id is null + and user_id is null </delete> <update id="renamePropertyKey" parameterType="map"> - update properties set prop_key=#{newKey} where prop_key=#{oldKey} + update properties set + prop_key=#{newKey} + where + prop_key=#{oldKey} </update> </mapper> diff --git a/sonar-db/src/test/java/org/sonar/db/property/PropertiesDaoTest.java b/sonar-db/src/test/java/org/sonar/db/property/PropertiesDaoTest.java index 2a0b8c1b6bf..4ad5862b347 100644 --- a/sonar-db/src/test/java/org/sonar/db/property/PropertiesDaoTest.java +++ b/sonar-db/src/test/java/org/sonar/db/property/PropertiesDaoTest.java @@ -20,12 +20,21 @@ package org.sonar.db.property; import com.google.common.collect.ImmutableMap; +import com.tngtech.java.junit.dataprovider.DataProvider; +import com.tngtech.java.junit.dataprovider.DataProviderRunner; +import com.tngtech.java.junit.dataprovider.UseDataProvider; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import javax.annotation.Nullable; import org.assertj.core.groups.Tuple; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; import org.sonar.api.utils.System2; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -36,20 +45,30 @@ import org.sonar.db.user.UserDto; import org.sonar.db.user.UserTesting; import static com.google.common.collect.Sets.newHashSet; -import static java.lang.String.valueOf; import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.tuple; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import static org.sonar.db.property.PropertyTesting.newComponentPropertyDto; import static org.sonar.db.property.PropertyTesting.newGlobalPropertyDto; import static org.sonar.db.property.PropertyTesting.newUserPropertyDto; +@RunWith(DataProviderRunner.class) public class PropertiesDaoTest { + private static final String VALUE_SIZE_4000 = String.format("%1$4000.4000s", "*"); + private static final String VALUE_SIZE_4001 = VALUE_SIZE_4000 + "P"; + private static final long DATE_1 = 1_555_000L; + private static final long DATE_2 = 1_666_000L; + private static final long DATE_3 = 1_777_000L; + private static final long DATE_4 = 1_888_000L; + private static final long DATE_5 = 1_999_000L; + + private System2 system2 = mock(System2.class); @Rule public ExpectedException thrown = ExpectedException.none(); @Rule - public DbTester dbTester = DbTester.create(System2.INSTANCE); + public DbTester dbTester = DbTester.create(system2); private DbClient dbClient = dbTester.getDbClient(); private DbSession session = dbTester.getSession(); @@ -57,133 +76,162 @@ public class PropertiesDaoTest { private PropertiesDao underTest = dbTester.getDbClient().propertiesDao(); @Test - public void shouldFindUsersForNotification() { - insertProject("uuid_45", 45); - insertProject("uuid_56", 56); - insertUser(1); - insertUser(2); - insertUser(3); - insertProperty(1, "notification.NewViolations.Email", "true", 45, 2); - insertProperty(2, "notification.NewViolations.Twitter", "true", null, 3); - insertProperty(3, "notification.NewViolations.Twitter", "true", 56, 1); - insertProperty(4, "notification.NewViolations.Twitter", "true", 56, 3); - - List<String> users = underTest.selectUsersForNotification("NewViolations", "Email", null); - assertThat(users).isEmpty(); - - users = underTest.selectUsersForNotification("NewViolations", "Email", "uuid_78"); - assertThat(users).isEmpty(); - - users = underTest.selectUsersForNotification("NewViolations", "Email", "uuid_45"); - assertThat(users).hasSize(1); - assertThat(users).containsOnly("user2"); - - users = underTest.selectUsersForNotification("NewViolations", "Twitter", null); - assertThat(users).hasSize(1); - assertThat(users).containsOnly("user3"); - - users = underTest.selectUsersForNotification("NewViolations", "Twitter", "uuid_78"); - assertThat(users).isEmpty(); - - users = underTest.selectUsersForNotification("NewViolations", "Twitter", "uuid_56"); - assertThat(users).hasSize(2); - assertThat(users).containsOnly("user1", "user3"); + public void shouldFindUsersForNotification() throws SQLException { + ComponentDto project1 = insertProject("uuid_45"); + ComponentDto project2 = insertProject("uuid_56"); + long userId1 = insertUser("user1"); + long userId2 = insertUser("user2"); + long userId3 = insertUser("user3"); + insertProperty("notification.NewViolations.Email", "true", project1.getId(), userId2); + insertProperty("notification.NewViolations.Twitter", "true", null, userId3); + insertProperty("notification.NewViolations.Twitter", "true", project2.getId(), userId1); + insertProperty("notification.NewViolations.Twitter", "true", project2.getId(), userId3); + + assertThat(underTest.selectUsersForNotification("NewViolations", "Email", null)) + .isEmpty(); + + assertThat(underTest.selectUsersForNotification("NewViolations", "Email", "uuid_78")) + .isEmpty(); + + assertThat(underTest.selectUsersForNotification("NewViolations", "Email", "uuid_45")) + .hasSize(1).containsOnly("user2"); + + assertThat(underTest.selectUsersForNotification("NewViolations", "Twitter", null)) + .hasSize(1) + .containsOnly("user3"); + + assertThat(underTest.selectUsersForNotification("NewViolations", "Twitter", "uuid_78")) + .isEmpty(); + + assertThat(underTest.selectUsersForNotification("NewViolations", "Twitter", "uuid_56")) + .hasSize(2) + .containsOnly("user1", "user3"); } @Test - public void findNotificationSubscribers() { - insertUser(1); - insertUser(2); - insertProject("PROJECT_A", 42); + public void findNotificationSubscribers() throws SQLException { + long userId1 = insertUser("user1"); + long userId2 = insertUser("user2"); + ComponentDto projectDto = insertProject("PROJECT_A"); + long projectId = projectDto.getId(); + String projectKey = projectDto.key(); + // global subscription - insertProperty(1, "notification.DispatcherWithGlobalSubscribers.Email", "true", null, 2); + insertProperty("notification.DispatcherWithGlobalSubscribers.Email", "true", null, userId2); // project subscription - insertProperty(2, "notification.DispatcherWithProjectSubscribers.Email", "true", 42, 1); - insertProperty(3, "notification.DispatcherWithGlobalAndProjectSubscribers.Email", "true", 56, 1); - insertProperty(4, "notification.DispatcherWithGlobalAndProjectSubscribers.Email", "true", 42, 1); + insertProperty("notification.DispatcherWithProjectSubscribers.Email", "true", projectId, userId1); + insertProperty("notification.DispatcherWithGlobalAndProjectSubscribers.Email", "true", 56L, userId1); + insertProperty("notification.DispatcherWithGlobalAndProjectSubscribers.Email", "true", projectId, userId1); // global subscription - insertProperty(5, "notification.DispatcherWithGlobalAndProjectSubscribers.Email", "true", null, 2); + insertProperty("notification.DispatcherWithGlobalAndProjectSubscribers.Email", "true", null, userId2); // Nobody is subscribed - List<String> users = underTest.selectNotificationSubscribers("NotSexyDispatcher", "Email", "project42"); - assertThat(users).isEmpty(); + assertThat(underTest.selectNotificationSubscribers("NotSexyDispatcher", "Email", projectKey)) + .isEmpty(); // Global subscribers - users = underTest.selectNotificationSubscribers("DispatcherWithGlobalSubscribers", "Email", "project42"); - assertThat(users).containsOnly("user2"); + assertThat(underTest.selectNotificationSubscribers("DispatcherWithGlobalSubscribers", "Email", projectKey)) + .containsOnly("user2"); - users = underTest.selectNotificationSubscribers("DispatcherWithGlobalSubscribers", "Email", null); - assertThat(users).containsOnly("user2"); + assertThat(underTest.selectNotificationSubscribers("DispatcherWithGlobalSubscribers", "Email", null)) + .containsOnly("user2"); // Project subscribers - users = underTest.selectNotificationSubscribers("DispatcherWithProjectSubscribers", "Email", "project42"); - assertThat(users).containsOnly("user1"); + assertThat(underTest.selectNotificationSubscribers("DispatcherWithProjectSubscribers", "Email", projectKey)) + .containsOnly("user1"); // Global + Project subscribers - users = underTest.selectNotificationSubscribers("DispatcherWithGlobalAndProjectSubscribers", "Email", "project42"); - assertThat(users).containsOnly("user1", "user2"); + assertThat(underTest.selectNotificationSubscribers("DispatcherWithGlobalAndProjectSubscribers", "Email", projectKey)) + .containsOnly("user1", "user2"); } @Test - public void hasNotificationSubscribers() { - insertUser(1); - insertUser(2); - insertProject("PROJECT_A", 42); + public void hasNotificationSubscribers() throws SQLException { + long userId1 = insertUser("user1"); + long userId2 = insertUser("user2"); + Long projectId = insertProject("PROJECT_A").getId(); // global subscription - insertProperty(1, "notification.DispatcherWithGlobalSubscribers.Email", "true", null, 2); + insertProperty("notification.DispatcherWithGlobalSubscribers.Email", "true", null, userId2); // project subscription - insertProperty(2, "notification.DispatcherWithProjectSubscribers.Email", "true", 42, 1); - insertProperty(3, "notification.DispatcherWithGlobalAndProjectSubscribers.Email", "true", 56, 1); - insertProperty(4, "notification.DispatcherWithGlobalAndProjectSubscribers.Email", "true", 42, 1); + insertProperty("notification.DispatcherWithProjectSubscribers.Email", "true", projectId, userId1); + insertProperty("notification.DispatcherWithGlobalAndProjectSubscribers.Email", "true", 56L, userId1); + insertProperty("notification.DispatcherWithGlobalAndProjectSubscribers.Email", "true", projectId, userId1); // global subscription - insertProperty(5, "notification.DispatcherWithGlobalAndProjectSubscribers.Email", "true", null, 2); + insertProperty("notification.DispatcherWithGlobalAndProjectSubscribers.Email", "true", null, userId2); // Nobody is subscribed - assertThat(underTest.hasProjectNotificationSubscribersForDispatchers("PROJECT_A", singletonList("NotSexyDispatcher"))).isFalse(); + assertThat(underTest.hasProjectNotificationSubscribersForDispatchers("PROJECT_A", singletonList("NotSexyDispatcher"))) + .isFalse(); // Global subscribers - assertThat(underTest.hasProjectNotificationSubscribersForDispatchers("PROJECT_A", singletonList("DispatcherWithGlobalSubscribers"))).isTrue(); + assertThat(underTest.hasProjectNotificationSubscribersForDispatchers("PROJECT_A", singletonList("DispatcherWithGlobalSubscribers"))) + .isTrue(); // Project subscribers - assertThat(underTest.hasProjectNotificationSubscribersForDispatchers("PROJECT_A", singletonList("DispatcherWithProjectSubscribers"))).isTrue(); - assertThat(underTest.hasProjectNotificationSubscribersForDispatchers("PROJECT_B", singletonList("DispatcherWithProjectSubscribers"))).isFalse(); + assertThat(underTest.hasProjectNotificationSubscribersForDispatchers("PROJECT_A", singletonList("DispatcherWithProjectSubscribers"))) + .isTrue(); + assertThat(underTest.hasProjectNotificationSubscribersForDispatchers("PROJECT_B", singletonList("DispatcherWithProjectSubscribers"))) + .isFalse(); // Global + Project subscribers - assertThat(underTest.hasProjectNotificationSubscribersForDispatchers("PROJECT_A", singletonList("DispatcherWithGlobalAndProjectSubscribers"))).isTrue(); - assertThat(underTest.hasProjectNotificationSubscribersForDispatchers("PROJECT_B", singletonList("DispatcherWithGlobalAndProjectSubscribers"))).isTrue(); + assertThat(underTest.hasProjectNotificationSubscribersForDispatchers("PROJECT_A", singletonList("DispatcherWithGlobalAndProjectSubscribers"))) + .isTrue(); + assertThat(underTest.hasProjectNotificationSubscribersForDispatchers("PROJECT_B", singletonList("DispatcherWithGlobalAndProjectSubscribers"))) + .isTrue(); } @Test - public void selectGlobalProperties() { + public void selectGlobalProperties() throws SQLException { // global - insertProperty(1, "global.one", "one", null, null); - insertProperty(2, "global.two", "two", null, null); + long id1 = insertProperty("global.one", "one", null, null); + long id2 = insertProperty("global.two", "two", null, null); List<PropertyDto> properties = underTest.selectGlobalProperties(); - assertThat(properties.size()).isEqualTo(2); - - PropertyDto first = findById(properties, 1); - assertThat(first.getKey()).isEqualTo("global.one"); - assertThat(first.getValue()).isEqualTo("one"); + assertThat(properties.size()) + .isEqualTo(2); + + assertThatDto(findById(properties, id1)) + .hasKey("global.one") + .hasNoUserId() + .hasNoResourceId() + .hasValue("one"); + + assertThatDto(findById(properties, id2)) + .hasKey("global.two") + .hasNoResourceId() + .hasNoUserId() + .hasValue("two"); + } - PropertyDto second = findById(properties, 2); - assertThat(second.getKey()).isEqualTo("global.two"); - assertThat(second.getValue()).isEqualTo("two"); + @Test + @UseDataProvider("allValuesForSelect") + public void selectGlobalProperties_supports_all_values(String dbValue, String expected) throws SQLException { + insertProperty("global.one", dbValue, null, null); + + List<PropertyDto> dtos = underTest.selectGlobalProperties(); + assertThat(dtos) + .hasSize(1); + assertThatDto(dtos.iterator().next()) + .hasKey("global.one") + .hasNoResourceId() + .hasNoUserId() + .hasValue(expected); } @Test - public void selectGlobalProperty() { + public void selectGlobalProperty() throws SQLException { // global - insertProperty(1, "global.one", "one", null, null); - insertProperty(2, "global.two", "two", null, null); + insertProperty("global.one", "one", null, null); + insertProperty("global.two", "two", null, null); // project - insertProperty(3, "project.one", "one", 10, null); + insertProperty("project.one", "one", 10L, null); // user - insertProperty(4, "user.one", "one", null, 100); + insertProperty("user.one", "one", null, 100L); - PropertyDto prop = underTest.selectGlobalProperty("global.one"); - assertThat(prop).isNotNull(); - assertThat(prop.getValue()).isEqualTo("one"); + assertThatDto(underTest.selectGlobalProperty("global.one")) + .hasNoResourceId() + .hasNoUserId() + .hasValue("one"); assertThat(underTest.selectGlobalProperty("project.one")).isNull(); assertThat(underTest.selectGlobalProperty("user.one")).isNull(); @@ -191,39 +239,80 @@ public class PropertiesDaoTest { } @Test - public void selectProjectProperties() { - insertProject("A", 10); + @UseDataProvider("allValuesForSelect") + public void selectGlobalProperty_supports_all_values(String dbValue, String expected) throws SQLException { + insertProperty("global.one", dbValue, null, null); + + assertThatDto(underTest.selectGlobalProperty("global.one")) + .hasNoResourceId() + .hasNoUserId() + .hasValue(expected); + } + + @Test + public void selectProjectProperties() throws SQLException { + ComponentDto projectDto = insertProject("A"); + long projectId = projectDto.getId(); // global - insertProperty(1, "global.one", "one", null, null); - insertProperty(2, "global.two", "two", null, null); + insertProperty("global.one", "one", null, null); + insertProperty("global.two", "two", null, null); // project - insertProperty(3, "project.one", "one", 10, null); - insertProperty(4, "project.two", "two", 10, null); + long id3 = insertProperty("project.one", "Pone", projectId, null); + long id4 = insertProperty("project.two", "Ptwo", projectId, null); + + List<PropertyDto> dtos = underTest.selectProjectProperties(projectDto.key()); + assertThat(dtos) + .hasSize(2); + assertThatDto(findById(dtos, id3)) + .hasKey("project.one") + .hasResourceId(projectId) + .hasValue("Pone"); + assertThatDto(findById(dtos, id4)) + .hasKey("project.two") + .hasResourceId(projectId) + .hasValue("Ptwo"); + } - List<PropertyDto> properties = underTest.selectProjectProperties("project10"); - assertThat(properties) - .hasSize(2) - .extracting("key", "value") - .containsOnly(tuple("project.one", "one"), tuple("project.two", "two")); + @Test + @UseDataProvider("allValuesForSelect") + public void selectProjectProperties_supports_all_values(String dbValue, String expected) throws SQLException { + ComponentDto projectDto = insertProject("A"); + insertProperty("project.one", dbValue, projectDto.getId(), null); + + List<PropertyDto> dtos = underTest.selectProjectProperties(projectDto.key()); + assertThat(dtos).hasSize(1); + assertThatDto(dtos.iterator().next()) + .hasKey("project.one") + .hasResourceId(projectDto.getId()) + .hasValue(expected); + } + + @DataProvider + public static Object[][] allValuesForSelect() { + return new Object[][] { + {null, ""}, + {"", ""}, + {"some value", "some value"}, + {VALUE_SIZE_4000, VALUE_SIZE_4000}, + {VALUE_SIZE_4001, VALUE_SIZE_4001} + }; } @Test - public void selectProjectProperty() { - insertProject("A", 10); - // global - insertProperty(1, "global.one", "one", null, null); - insertProperty(2, "global.two", "two", null, null); - // project - insertProperty(3, "project.one", "one", 10, null); + public void selectProjectProperty() throws SQLException { + insertProperty("project.one", "one", 10L, null); PropertyDto property = underTest.selectProjectProperty(10L, "project.one"); - assertThat(property.getKey()).isEqualTo("project.one"); - assertThat(property.getValue()).isEqualTo("one"); + assertThatDto(property) + .hasKey("project.one") + .hasResourceId(10L) + .hasNoUserId() + .hasValue("one"); } @Test - public void select_module_properties_tree() { + public void selectEnabledDescendantModuleProperties() { dbTester.prepareDbUnit(getClass(), "select_module_properties_tree.xml"); List<PropertyDto> properties = underTest.selectEnabledDescendantModuleProperties("ABCD", dbTester.getSession()); @@ -243,8 +332,38 @@ public class PropertiesDaoTest { } @Test - public void select_by_query() { - dbTester.prepareDbUnit(getClass(), "select_by_query.xml"); + @UseDataProvider("allValuesForSelect") + public void selectEnabledDescendantModuleProperties_supports_all_values(String dbValue, String expected) throws SQLException { + String projectUuid = "A"; + ComponentDto project = ComponentTesting.newProjectDto(projectUuid); + dbClient.componentDao().insert(session, project); + long projectId = project.getId(); + insertProperty("project.one", dbValue, projectId, null); + + List<PropertyDto> dtos = underTest.selectEnabledDescendantModuleProperties(projectUuid, dbTester.getSession()); + assertThat(dtos) + .hasSize(1); + assertThatDto(dtos.iterator().next()) + .hasKey("project.one") + .hasResourceId(projectId) + .hasNoUserId() + .hasValue(expected); + } + + @Test + public void select_by_query() throws SQLException { + // global + insertProperty("global.one", "one", null, null); + insertProperty("global.two", "two", null, null); + // struts + insertProperty("struts.one", "one", 10L, null); + // commons + insertProperty("commonslang.one", "one", 11L, null); + // user + insertProperty("user.one", "one", null, 100L); + insertProperty("user.two", "two", 10L, 100L); + // other + insertProperty("other.one", "one", 12L, null); List<PropertyDto> results = underTest.selectByQuery(PropertyQuery.builder().setKey("user.two").setComponentId(10L).setUserId(100).build(), dbTester.getSession()); assertThat(results).hasSize(1); @@ -257,24 +376,27 @@ public class PropertiesDaoTest { @Test public void select_global_properties_by_keys() throws Exception { - ComponentDto project = ComponentTesting.newProjectDto(); - dbClient.componentDao().insert(session, project); - UserDto user = UserTesting.newUserDto(); - dbClient.userDao().insert(session, user); + insertProject("A"); + long userId = insertUser("B"); String key = "key"; String anotherKey = "anotherKey"; - insertProperties( - newGlobalPropertyDto().setKey(key), - newComponentPropertyDto(project).setKey(key), - newUserPropertyDto(user).setKey(key), - newGlobalPropertyDto().setKey(anotherKey)); - - assertThat(underTest.selectGlobalPropertiesByKeys(session, newHashSet(key))).extracting("key").containsOnly(key); - assertThat(underTest.selectGlobalPropertiesByKeys(session, newHashSet(key, anotherKey))).extracting("key").containsOnly(key, anotherKey); - assertThat(underTest.selectGlobalPropertiesByKeys(session, newHashSet(key, anotherKey, "unknown"))).extracting("key").containsOnly(key, anotherKey); - - assertThat(underTest.selectGlobalPropertiesByKeys(session, newHashSet("unknown"))).isEmpty(); + insertProperty(key, "value", null, null); + insertProperty(key, "value", 10L, null); + insertProperty(key, "value", null, userId); + insertProperty(anotherKey, "value", null, null); + + assertThat(underTest.selectGlobalPropertiesByKeys(session, newHashSet(key))) + .extracting("key") + .containsOnly(key); + assertThat(underTest.selectGlobalPropertiesByKeys(session, newHashSet(key, anotherKey))) + .extracting("key") + .containsOnly(key, anotherKey); + assertThat(underTest.selectGlobalPropertiesByKeys(session, newHashSet(key, anotherKey, "unknown"))) + .extracting("key") + .containsOnly(key, anotherKey); + assertThat(underTest.selectGlobalPropertiesByKeys(session, newHashSet("unknown"))) + .isEmpty(); } @Test @@ -337,99 +459,527 @@ public class PropertiesDaoTest { } @Test - public void setProperty_update() { - dbTester.prepareDbUnit(getClass(), "update.xml"); + public void saveProperty_inserts_global_properties_when_they_do_not_exist_in_db() { + when(system2.now()).thenReturn(DATE_1, DATE_2, DATE_3, DATE_4, DATE_5); + + underTest.saveProperty(new PropertyDto().setKey("global.null").setValue(null)); + underTest.saveProperty(new PropertyDto().setKey("global.empty").setValue("")); + underTest.saveProperty(new PropertyDto().setKey("global.text").setValue("some text")); + underTest.saveProperty(new PropertyDto().setKey("global.4000").setValue(VALUE_SIZE_4000)); + underTest.saveProperty(new PropertyDto().setKey("global.clob").setValue(VALUE_SIZE_4001)); + + assertThatPropertiesRow("global.null") + .hasNoResourceId() + .hasNoUserId() + .isEmpty() + .hasCreatedAt(DATE_1); + assertThatPropertiesRow("global.empty") + .hasNoResourceId() + .hasNoUserId() + .isEmpty() + .hasCreatedAt(DATE_2); + assertThatPropertiesRow("global.text") + .hasNoResourceId() + .hasNoUserId() + .hasTextValue("some text") + .hasCreatedAt(DATE_3); + assertThatPropertiesRow("global.4000") + .hasNoResourceId() + .hasNoUserId() + .hasTextValue(VALUE_SIZE_4000) + .hasCreatedAt(DATE_4); + assertThatPropertiesRow("global.clob") + .hasNoResourceId() + .hasNoUserId() + .hasClobValue(VALUE_SIZE_4001) + .hasCreatedAt(DATE_5); + } - underTest.insertProperty(new PropertyDto().setKey("global.key").setValue("new_global")); - underTest.insertProperty(new PropertyDto().setKey("project.key").setResourceId(10L).setValue("new_project")); - underTest.insertProperty(new PropertyDto().setKey("user.key").setUserId(100L).setValue("new_user")); - underTest.insertProperty(new PropertyDto().setKey("null.value").setValue(null)); + @Test + public void saveProperty_inserts_component_properties_when_they_do_not_exist_in_db() { + when(system2.now()).thenReturn(DATE_1, DATE_2, DATE_3, DATE_4, DATE_5); + + long resourceId = 12; + underTest.saveProperty(new PropertyDto().setKey("component.null").setResourceId(resourceId).setValue(null)); + underTest.saveProperty(new PropertyDto().setKey("component.empty").setResourceId(resourceId).setValue("")); + underTest.saveProperty(new PropertyDto().setKey("component.text").setResourceId(resourceId).setValue("some text")); + underTest.saveProperty(new PropertyDto().setKey("component.4000").setResourceId(resourceId).setValue(VALUE_SIZE_4000)); + underTest.saveProperty(new PropertyDto().setKey("component.clob").setResourceId(resourceId).setValue(VALUE_SIZE_4001)); + + assertThatPropertiesRow("component.null") + .hasResourceId(resourceId) + .hasNoUserId() + .isEmpty() + .hasCreatedAt(DATE_1); + assertThatPropertiesRow("component.empty") + .hasResourceId(resourceId) + .hasNoUserId() + .isEmpty() + .hasCreatedAt(DATE_2); + assertThatPropertiesRow("component.text") + .hasResourceId(resourceId) + .hasNoUserId() + .hasTextValue("some text") + .hasCreatedAt(DATE_3); + assertThatPropertiesRow("component.4000") + .hasResourceId(resourceId) + .hasNoUserId() + .hasTextValue(VALUE_SIZE_4000) + .hasCreatedAt(DATE_4); + assertThatPropertiesRow("component.clob") + .hasResourceId(resourceId) + .hasNoUserId() + .hasClobValue(VALUE_SIZE_4001) + .hasCreatedAt(DATE_5); + } - dbTester.assertDbUnit(getClass(), "update-result.xml", "properties"); + @Test + public void saveProperty_inserts_user_properties_when_they_do_not_exist_in_db() { + when(system2.now()).thenReturn(DATE_1, DATE_2, DATE_3, DATE_4, DATE_5); + + long userId = 100; + underTest.saveProperty(new PropertyDto().setKey("user.null").setUserId(userId).setValue(null)); + underTest.saveProperty(new PropertyDto().setKey("user.empty").setUserId(userId).setValue("")); + underTest.saveProperty(new PropertyDto().setKey("user.text").setUserId(userId).setValue("some text")); + underTest.saveProperty(new PropertyDto().setKey("user.4000").setUserId(userId).setValue(VALUE_SIZE_4000)); + underTest.saveProperty(new PropertyDto().setKey("user.clob").setUserId(userId).setValue(VALUE_SIZE_4001)); + + assertThatPropertiesRow("user.null") + .hasNoResourceId() + .hasUserId(userId) + .isEmpty() + .hasCreatedAt(DATE_1); + assertThatPropertiesRow("user.empty") + .hasNoResourceId() + .hasUserId(userId) + .isEmpty() + .hasCreatedAt(DATE_2); + assertThatPropertiesRow("user.text") + .hasNoResourceId() + .hasUserId(userId) + .hasTextValue("some text") + .hasCreatedAt(DATE_3); + assertThatPropertiesRow("user.4000") + .hasNoResourceId() + .hasUserId(userId) + .hasTextValue(VALUE_SIZE_4000) + .hasCreatedAt(DATE_4); + assertThatPropertiesRow("user.clob") + .hasNoResourceId() + .hasUserId(userId) + .hasClobValue(VALUE_SIZE_4001) + .hasCreatedAt(DATE_5); } @Test - public void setProperty_insert() { - dbTester.prepareDbUnit(getClass(), "insert.xml"); + @UseDataProvider("valueUpdatesDataProvider") + public void saveProperty_deletes_then_inserts_global_properties_when_they_exist_in_db(@Nullable String oldValue, @Nullable String newValue) throws SQLException { + long id = insertProperty("global", oldValue, null, null, DATE_1); + when(system2.now()).thenReturn(DATE_4); + + underTest.saveProperty(new PropertyDto().setKey("global").setValue(newValue)); + + assertThatPropertiesRow(id) + .doesNotExist(); + + PropertiesRowAssert propertiesRowAssert = assertThatPropertiesRow("global") + .hasNoResourceId() + .hasNoUserId() + .hasCreatedAt(DATE_4); + if (newValue == null || newValue.isEmpty()) { + propertiesRowAssert.isEmpty(); + } else if (newValue.length() > 4000) { + propertiesRowAssert.hasClobValue(newValue); + } else { + propertiesRowAssert.hasTextValue(newValue); + } + } + + @Test + @UseDataProvider("valueUpdatesDataProvider") + public void saveProperty_deletes_then_inserts_component_properties_when_they_exist_in_db(@Nullable String oldValue, @Nullable String newValue) throws SQLException { + long resourceId = 999L; + long id = insertProperty("global", oldValue, resourceId, null, DATE_1); + when(system2.now()).thenReturn(DATE_4); + + underTest.saveProperty(new PropertyDto().setKey("global").setResourceId(resourceId).setValue(newValue)); + + assertThatPropertiesRow(id) + .doesNotExist(); + + PropertiesRowAssert propertiesRowAssert = assertThatPropertiesRow("global") + .hasResourceId(resourceId) + .hasNoUserId() + .hasCreatedAt(DATE_4); + if (newValue == null || newValue.isEmpty()) { + propertiesRowAssert.isEmpty(); + } else if (newValue.length() > 4000) { + propertiesRowAssert.hasClobValue(newValue); + } else { + propertiesRowAssert.hasTextValue(newValue); + } + } - underTest.insertProperty(new PropertyDto().setKey("global.key").setValue("new_global")); - underTest.insertProperty(new PropertyDto().setKey("project.key").setResourceId(10L).setValue("new_project")); - underTest.insertProperty(new PropertyDto().setKey("user.key").setUserId(100L).setValue("new_user")); + @Test + @UseDataProvider("valueUpdatesDataProvider") + public void saveProperty_deletes_then_inserts_user_properties_when_they_exist_in_db(@Nullable String oldValue, @Nullable String newValue) throws SQLException { + long userId = 90L; + long id = insertProperty("global", oldValue, null, userId, DATE_1); + when(system2.now()).thenReturn(DATE_4); + + underTest.saveProperty(new PropertyDto().setKey("global").setUserId(userId).setValue(newValue)); + + assertThatPropertiesRow(id) + .doesNotExist(); + + PropertiesRowAssert propertiesRowAssert = assertThatPropertiesRow("global") + .hasNoResourceId() + .hasUserId(userId) + .hasCreatedAt(DATE_4); + if (newValue == null || newValue.isEmpty()) { + propertiesRowAssert.isEmpty(); + } else if (newValue.length() > 4000) { + propertiesRowAssert.hasClobValue(newValue); + } else { + propertiesRowAssert.hasTextValue(newValue); + } + } - dbTester.assertDbUnit(getClass(), "insert-result.xml", "properties"); + @DataProvider + public static Object[][] valueUpdatesDataProvider() { + return new Object[][] { + {null, null}, + {null, ""}, + {null, "some value"}, + {null, VALUE_SIZE_4000}, + {null, VALUE_SIZE_4001}, + {"", null}, + {"", ""}, + {"", "some value"}, + {"", VALUE_SIZE_4000}, + {"", VALUE_SIZE_4001}, + {"a value", null}, + {"a value", ""}, + {"a value", "a value"}, + {"a value", "some value"}, + {"a value", VALUE_SIZE_4000}, + {"a value", VALUE_SIZE_4001}, + {VALUE_SIZE_4000, null}, + {VALUE_SIZE_4000, ""}, + {VALUE_SIZE_4000, "a value"}, + {VALUE_SIZE_4000, VALUE_SIZE_4000}, + {VALUE_SIZE_4000, VALUE_SIZE_4000.substring(1) + "a"}, + {VALUE_SIZE_4000, VALUE_SIZE_4001}, + {VALUE_SIZE_4001, null}, + {VALUE_SIZE_4001, ""}, + {VALUE_SIZE_4001, "a value"}, + {VALUE_SIZE_4001, VALUE_SIZE_4000}, + {VALUE_SIZE_4001, VALUE_SIZE_4001}, + {VALUE_SIZE_4001, VALUE_SIZE_4001 + "dfsdfs"}, + }; } @Test - public void delete_property_by_id() { - dbTester.prepareDbUnit(getClass(), "delete.xml"); + @UseDataProvider("possibleValuesProvider") + public void deleteById(String value) throws SQLException { + long id1 = insertProperty("global.key", value, null, null); + long id2 = insertProperty("component.key", value, 10L, null); + long id3 = insertProperty("user.key", value, null, 100L); + + underTest.deleteById(dbTester.getSession(), id1); + dbTester.getSession().commit(); - underTest.deleteById(dbTester.getSession(), 1L); + assertThatPropertiesRow(id1) + .doesNotExist(); + assertThatPropertiesRow(id2) + .hasKey("component.key"); + assertThatPropertiesRow(id3) + .hasKey("user.key"); + + underTest.deleteById(dbTester.getSession(), id2); + dbTester.getSession().commit(); + + assertThatPropertiesRow(id2) + .doesNotExist(); + assertThatPropertiesRow(id3) + .hasKey("user.key"); + + underTest.deleteById(dbTester.getSession(), id3); dbTester.getSession().commit(); - dbTester.assertDbUnit(getClass(), "delete-result.xml", "properties"); + assertThatPropertiesRow(id3) + .doesNotExist(); } - @Test - public void delete_project_property() { - dbTester.prepareDbUnit(getClass(), "delete_project_property.xml"); + @DataProvider + public static Object[][] possibleValuesProvider() { + return new Object[][] { + {null}, + {""}, + {"some value"}, + {VALUE_SIZE_4000}, + {VALUE_SIZE_4001} + }; + } - underTest.deleteProjectProperty("struts.one", 10L); + @Test + public void deleteById_does_not_fail_if_row_with_specified_id_does_not_exist() { + underTest.deleteById(dbTester.getSession(), 12L); + dbTester.getSession().commit(); + } - dbTester.assertDbUnit(getClass(), "delete_project_property-result.xml", "properties"); + @Test + public void delete_project_property() throws SQLException { + long projectId1 = insertProject("A").getId(); + long projectId2 = insertProject("B").getId(); + long projectId3 = insertProject("C").getId(); + long id1 = insertProperty("global.one", "one", null, null); + long id2 = insertProperty("global.two", "two", null, null); + long id3 = insertProperty("struts.one", "one", projectId1, null); + long id4 = insertProperty("commonslang.one", "one", projectId2, null); + long id5 = insertProperty("user.one", "one", null, 100L); + long id6 = insertProperty("user.two", "two", null, 100L); + long id7 = insertProperty("other.one", "one", projectId3, null); + + underTest.deleteProjectProperty("struts.one", projectId1); + + assertThatPropertiesRow(id1) + .hasKey("global.one") + .hasNoResourceId() + .hasNoUserId() + .hasTextValue("one"); + assertThatPropertiesRow(id2) + .hasKey("global.two") + .hasNoResourceId() + .hasNoUserId() + .hasTextValue("two"); + assertThatPropertiesRow(id3) + .doesNotExist(); + assertThatPropertiesRow(id4) + .hasKey("commonslang.one") + .hasResourceId(projectId2) + .hasNoUserId() + .hasTextValue("one"); + assertThatPropertiesRow(id5) + .hasKey("user.one") + .hasNoResourceId() + .hasUserId(100) + .hasTextValue("one"); + assertThatPropertiesRow(id6) + .hasKey("user.two") + .hasNoResourceId() + .hasUserId(100) + .hasTextValue("two"); + assertThatPropertiesRow(id7) + .hasKey("other.one") + .hasResourceId(projectId3) + .hasNoUserId() + .hasTextValue("one"); } @Test - public void delete_project_properties() { - dbTester.prepareDbUnit(getClass(), "delete_project_properties.xml"); + public void delete_project_properties() throws SQLException { + long id1 = insertProperty("sonar.profile.java", "Sonar Way", 1L, null); + long id2 = insertProperty("sonar.profile.java", "Sonar Way", 2L, null); + + long id3 = insertProperty("sonar.profile.java", "Sonar Way", null, null); + + long id4 = insertProperty("sonar.profile.js", "Sonar Way", 1L, null); + long id5 = insertProperty("sonar.profile.js", "Sonar Way", 2L, null); + long id6 = insertProperty("sonar.profile.js", "Sonar Way", null, null); underTest.deleteProjectProperties("sonar.profile.java", "Sonar Way"); - dbTester.assertDbUnit(getClass(), "delete_project_properties-result.xml", "properties"); + assertThatPropertiesRow(id1) + .doesNotExist(); + assertThatPropertiesRow(id2) + .doesNotExist(); + assertThatPropertiesRow(id3) + .hasKey("sonar.profile.java") + .hasNoResourceId() + .hasNoUserId() + .hasTextValue("Sonar Way"); + assertThatPropertiesRow(id4) + .hasKey("sonar.profile.js") + .hasResourceId(1) + .hasNoUserId() + .hasTextValue("Sonar Way"); + assertThatPropertiesRow(id5) + .hasKey("sonar.profile.js") + .hasResourceId(2) + .hasNoUserId() + .hasTextValue("Sonar Way"); + assertThatPropertiesRow(id6) + .hasKey("sonar.profile.js") + .hasNoResourceId() + .hasNoUserId() + .hasTextValue("Sonar Way"); } @Test - public void deleteGlobalProperty() { - dbTester.prepareDbUnit(getClass(), "deleteGlobalProperty.xml"); + public void deleteGlobalProperty() throws SQLException { + // global + long id1 = insertProperty("global.key", "new_global", null, null); + long id2 = insertProperty("to_be_deleted", "xxx", null, null); + // project - do not delete this project property that has the same key + long id3 = insertProperty("to_be_deleted", "new_project", 10L, null); + // user + long id4 = insertProperty("user.key", "new_user", null, 100L); underTest.deleteGlobalProperty("to_be_deleted"); - dbTester.assertDbUnit(getClass(), "deleteGlobalProperty-result.xml", "properties"); + assertThatPropertiesRow(id1) + .hasKey("global.key") + .hasNoUserId() + .hasNoResourceId() + .hasTextValue("new_global"); + assertThatPropertiesRow(id2) + .doesNotExist(); + assertThatPropertiesRow("to_be_deleted", null, null) + .doesNotExist(); + assertThatPropertiesRow(id3) + .hasKey("to_be_deleted") + .hasResourceId(10) + .hasNoUserId() + .hasTextValue("new_project"); + assertThatPropertiesRow(id4) + .hasKey("user.key") + .hasNoResourceId() + .hasUserId(100) + .hasTextValue("new_user"); + } @Test - public void insertGlobalProperties() { - dbTester.prepareDbUnit(getClass(), "insertGlobalProperties.xml"); - - underTest.insertGlobalProperties(ImmutableMap.of("to_be_inserted", "inserted")); - - dbTester.assertDbUnitTable(getClass(), "insertGlobalProperties-result.xml", "properties", "prop_key", "text_value", "resource_id", "user_id"); + public void saveGlobalProperties_insert_property_if_does_not_exist_in_db() { + when(system2.now()).thenReturn(DATE_1, DATE_2, DATE_3, DATE_4, DATE_5); + + underTest.saveGlobalProperties(mapOf( + "null_value_property", null, + "empty_value_property", "", + "text_value_property", "dfdsfsd", + "4000_char_value_property", VALUE_SIZE_4000, + "clob_value_property", VALUE_SIZE_4001)); + + assertThatPropertiesRow("null_value_property") + .hasNoResourceId() + .hasNoUserId() + .isEmpty() + .hasCreatedAt(DATE_1); + assertThatPropertiesRow("empty_value_property") + .hasNoResourceId() + .hasNoUserId() + .isEmpty() + .hasCreatedAt(DATE_2); + assertThatPropertiesRow("text_value_property") + .hasNoResourceId() + .hasNoUserId() + .hasTextValue("dfdsfsd") + .hasCreatedAt(DATE_3); + assertThatPropertiesRow("4000_char_value_property") + .hasNoResourceId() + .hasNoUserId() + .hasTextValue(VALUE_SIZE_4000) + .hasCreatedAt(DATE_4); + assertThatPropertiesRow("clob_value_property") + .hasNoResourceId() + .hasNoUserId() + .hasClobValue(VALUE_SIZE_4001) + .hasCreatedAt(DATE_5); } @Test - public void updateGlobalProperties() { - dbTester.prepareDbUnit(getClass(), "updateGlobalProperties.xml"); + public void saveGlobalProperties_delete_and_insert_new_value_when_property_exists_in_db() throws SQLException { + long id = insertProperty("to_be_updated", "old_value", null, null, DATE_1); + when(system2.now()).thenReturn(DATE_3); - underTest.insertGlobalProperties(ImmutableMap.of("to_be_updated", "updated")); + underTest.saveGlobalProperties(ImmutableMap.of("to_be_updated", "new value")); - dbTester.assertDbUnitTable(getClass(), "updateGlobalProperties-result.xml", "properties", "prop_key", "text_value", "resource_id", "user_id"); - } + assertThatPropertiesRow(id) + .doesNotExist(); - @Test - public void renamePropertyKey() { - dbTester.prepareDbUnit(getClass(), "renamePropertyKey.xml"); + assertThatPropertiesRow("to_be_updated") + .hasNoResourceId() + .hasNoUserId() + .hasTextValue("new value") + .hasCreatedAt(DATE_3); + } - underTest.renamePropertyKey("sonar.license.secured", "sonar.license"); + private static Map<String, String> mapOf(String... values) { + // use LinkedHashMap to keep order of array + Map<String, String> res = new LinkedHashMap<>(values.length / 2); + Iterator<String> iterator = Arrays.asList(values).iterator(); + while (iterator.hasNext()) { + res.put(iterator.next(), iterator.next()); + } + return res; + } - dbTester.assertDbUnitTable(getClass(), "renamePropertyKey-result.xml", "properties", "prop_key", "text_value", "resource_id", "user_id"); + @Test + public void renamePropertyKey_updates_global_component_and_user_properties() throws SQLException { + long id1 = insertProperty("foo", "bar", null, null, DATE_1); + long id2 = insertProperty("old_name", "doc1", null, null, DATE_1); + long id3 = insertProperty("old_name", "doc2", 15L, null, DATE_1); + long id4 = insertProperty("old_name", "doc3", 16L, null, DATE_1); + long id5 = insertProperty("old_name", "doc4", null, 100L, DATE_1); + long id6 = insertProperty("old_name", "doc5", null, 101L, DATE_1); + + underTest.renamePropertyKey("old_name", "new_name"); + + assertThatPropertiesRow(id1) + .hasKey("foo") + .hasNoUserId() + .hasNoResourceId() + .hasTextValue("bar") + .hasCreatedAt(DATE_1); + assertThatPropertiesRow(id2) + .hasKey("new_name") + .hasNoResourceId() + .hasNoUserId() + .hasTextValue("doc1") + .hasCreatedAt(DATE_1); + assertThatPropertiesRow(id3) + .hasKey("new_name") + .hasResourceId(15) + .hasNoUserId() + .hasTextValue("doc2") + .hasCreatedAt(DATE_1); + assertThatPropertiesRow(id4) + .hasKey("new_name") + .hasResourceId(16) + .hasNoUserId() + .hasTextValue("doc3") + .hasCreatedAt(DATE_1); + assertThatPropertiesRow(id5) + .hasKey("new_name") + .hasNoResourceId() + .hasUserId(100) + .hasTextValue("doc4") + .hasCreatedAt(DATE_1); + assertThatPropertiesRow(id6) + .hasKey("new_name") + .hasNoResourceId() + .hasUserId(101) + .hasTextValue("doc5") + .hasCreatedAt(DATE_1); } @Test - public void should_not_rename_if_same_key() { - dbTester.prepareDbUnit(getClass(), "should_not_rename_if_same_key.xml"); + public void rename_to_same_key_has_no_effect() throws SQLException { + long now = 1_890_999L; + long id = insertProperty("foo", "bar", null, null, now); + + assertThatPropertiesRow(id) + .hasCreatedAt(now); underTest.renamePropertyKey("foo", "foo"); - dbTester.assertDbUnitTable(getClass(), "should_not_rename_if_same_key-result.xml", "properties", "prop_key", "text_value", "resource_id", "user_id"); + assertThatPropertiesRow(id) + .hasKey("foo") + .hasNoUserId() + .hasNoResourceId() + .hasTextValue("bar") + .hasCreatedAt(now); } @Test @@ -444,7 +994,7 @@ public class PropertiesDaoTest { underTest.renamePropertyKey(null, "foo"); } - private PropertyDto findById(List<PropertyDto> properties, int id) { + private PropertyDto findById(List<PropertyDto> properties, long id) { for (PropertyDto property : properties) { if (property.getId() == id) { return property; @@ -455,35 +1005,61 @@ public class PropertiesDaoTest { private void insertProperties(PropertyDto... properties) { for (PropertyDto propertyDto : properties) { - underTest.insertProperty(session, propertyDto); + underTest.saveProperty(session, propertyDto); } session.commit(); } - private void insertProperty(int id, String key, String value, @Nullable Integer resourceId, @Nullable Integer userId) { - dbTester.executeInsert("PROPERTIES", - "ID", valueOf(id), - "prop_key", key, - "text_value", value, - "resource_id", resourceId == null ? null : valueOf(resourceId), - "user_id", userId == null ? null : valueOf(userId)); - dbTester.commit(); + private long insertProperty(String key, @Nullable String value, @Nullable Long resourceId, @Nullable Long userId, long createdAt) throws SQLException { + when(system2.now()).thenReturn(createdAt); + return insertProperty(key, value, resourceId, userId); } - private void insertProject(String uuid, int id) { - dbTester.executeInsert("PROJECTS", - "uuid", uuid, - "uuid_path", "NOT_USED", - "root_uuid", uuid, - "kee", "project" + id, - "id", valueOf(id)); - dbTester.commit(); + private long insertProperty(String key, @Nullable String value, @Nullable Long resourceId, @Nullable Long userId) throws SQLException { + DbSession session = dbTester.getSession(); + PropertyDto dto = new PropertyDto().setKey(key) + .setResourceId(resourceId == null ? null : resourceId.longValue()) + .setUserId(userId == null ? null : userId) + .setValue(value); + dbTester.getDbClient().propertiesDao().saveProperty(session, dto); + session.commit(); + + return (long) dbTester.selectFirst(session, "select id as \"id\" from properties" + + " where prop_key='" + key + "'" + + " and user_id" + (userId == null ? " is null" : "='" + userId + "'") + + " and resource_id" + (resourceId == null ? " is null" : "='" + resourceId + "'")).get("id"); } - private void insertUser(int id) { - dbTester.executeInsert("USERS", - "id", valueOf(id), - "login", "user" + id); + private ComponentDto insertProject(String uuid) { + String key = "project" + uuid; + ComponentDto project = ComponentTesting.newProjectDto(uuid).setKey(key); + dbClient.componentDao().insert(session, project); dbTester.commit(); + return project; } + + private long insertUser(String login) { + UserDto dto = new UserDto().setLogin(login); + DbSession session = dbTester.getSession(); + dbClient.userDao().insert(session, dto); + session.commit(); + return dto.getId(); + } + + private static PropertyDtoAssert assertThatDto(@Nullable PropertyDto dto) { + return new PropertyDtoAssert(dto); + } + + private PropertiesRowAssert assertThatPropertiesRow(String key, @Nullable Integer userId, @Nullable Integer componentId) { + return new PropertiesRowAssert(dbTester, key, userId, componentId); + } + + private PropertiesRowAssert assertThatPropertiesRow(String key) { + return new PropertiesRowAssert(dbTester, key); + } + + private PropertiesRowAssert assertThatPropertiesRow(long id) { + return new PropertiesRowAssert(dbTester, id); + } + } diff --git a/sonar-db/src/test/java/org/sonar/db/property/PropertiesRow.java b/sonar-db/src/test/java/org/sonar/db/property/PropertiesRow.java new file mode 100644 index 00000000000..e677c16cc0e --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/property/PropertiesRow.java @@ -0,0 +1,77 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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.sonar.db.property; + +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + +final class PropertiesRow { + private final String key; + private final Long userId; + private final Long resourceId; + private final Boolean empty; + private final String textValue; + private final String clobValue; + private final Long createdAt; + + public PropertiesRow(String key, @Nullable Long userId, @Nullable Long resourceId, + @Nullable Boolean empty, @Nullable String textValue, @Nullable String clobValue, + @Nullable Long createdAt) { + this.key = key; + this.userId = userId; + this.resourceId = resourceId; + this.empty = empty; + this.textValue = textValue; + this.clobValue = clobValue; + this.createdAt = createdAt; + } + + public String getKey() { + return key; + } + + public Long getUserId() { + return userId; + } + + public Long getResourceId() { + return resourceId; + } + + @CheckForNull + public Boolean getEmpty() { + return empty; + } + + @CheckForNull + public String getTextValue() { + return textValue; + } + + @CheckForNull + public String getClobValue() { + return clobValue; + } + + @CheckForNull + public Long getCreatedAt() { + return createdAt; + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/property/PropertiesRowAssert.java b/sonar-db/src/test/java/org/sonar/db/property/PropertiesRowAssert.java new file mode 100644 index 00000000000..d64838394e9 --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/property/PropertiesRowAssert.java @@ -0,0 +1,203 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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.sonar.db.property; + +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Supplier; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; +import org.assertj.core.api.AbstractAssert; +import org.sonar.db.DbTester; + +import static com.google.common.base.Preconditions.checkState; +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; +import static java.util.Objects.requireNonNull; + +final class PropertiesRowAssert extends AbstractAssert<PropertiesRowAssert, PropertiesRow> { + + PropertiesRowAssert(DbTester dbTester, String propertyKey, @Nullable Integer userId, @Nullable Integer componentId) { + super( + asInternalProperty( + dbTester, + () -> " where prop_key='" + propertyKey + "'" + + " and user_id" + (userId == null ? " is null" : "='" + userId + "'") + + " and resource_id" + (componentId == null ? " is null" : "='" + componentId + "'")), + PropertiesRowAssert.class); + } + + PropertiesRowAssert(DbTester dbTester, String key) { + super(asInternalProperty(dbTester, () -> " where prop_key='" + key + "'"), PropertiesRowAssert.class); + } + + PropertiesRowAssert(DbTester dbTester, long id) { + super(asInternalProperty(dbTester, () -> " where id=" + id), PropertiesRowAssert.class); + } + + @CheckForNull + private static PropertiesRow asInternalProperty(DbTester dbTester, Supplier<String> whereClauseSupplier) { + String whereClause = whereClauseSupplier.get(); + List<Map<String, Object>> rows = dbTester.select( + "select" + + " prop_key as \"key\", user_id as \"userId\", resource_id as \"resourceId\", is_empty as \"isEmpty\", text_value as \"textValue\", clob_value as \"clobValue\", created_at as \"createdAt\"" + + + " from properties" + + whereClause); + checkState(rows.size() < 2, "More than one property found for where clause \"" + whereClause + "\""); + if (rows.isEmpty()) { + return null; + } else { + Map<String, Object> row = rows.iterator().next(); + return new PropertiesRow( + (String) row.get("key"), + (Long) row.get("userId"), + (Long) row.get("resourceId"), + toBoolean(row.get("isEmpty")), + (String) row.get("textValue"), + (String) row.get("clobValue"), + (Long) row.get("createdAt")); + } + } + + private static Boolean toBoolean(Object flag) { + if (flag instanceof Boolean) { + return (Boolean) flag; + } + if (flag instanceof Long) { + Long longBoolean = (Long) flag; + return longBoolean.equals(1L); + } + throw new IllegalArgumentException("Unsupported object type returned for column \"isEmpty\": " + flag.getClass()); + } + + public void doesNotExist() { + isNull(); + } + + public PropertiesRowAssert hasKey(String expected) { + isNotNull(); + + if (!Objects.equals(actual.getKey(), expected)) { + failWithMessage("Expected PropertiesRow to have column PROP_KEY to be <%s> but was <%s>", expected, actual.getKey()); + } + + return this; + } + + public PropertiesRowAssert hasNoUserId() { + isNotNull(); + + if (actual.getUserId() != null) { + failWithMessage("Expected PropertiesRow to have column USER_ID to be null but was <%s>", actual.getUserId()); + } + + return this; + } + + public PropertiesRowAssert hasUserId(long expected) { + isNotNull(); + + if (!Objects.equals(actual.getUserId(), expected)) { + failWithMessage("Expected PropertiesRow to have column USER_ID to be <%s> but was <%s>", true, actual.getUserId()); + } + + return this; + } + + public PropertiesRowAssert hasNoResourceId() { + isNotNull(); + + if (actual.getResourceId() != null) { + failWithMessage("Expected PropertiesRow to have column RESOURCE_ID to be null but was <%s>", actual.getResourceId()); + } + + return this; + } + + public PropertiesRowAssert hasResourceId(long expected) { + isNotNull(); + + if (!Objects.equals(actual.getResourceId(), expected)) { + failWithMessage("Expected PropertiesRow to have column RESOURCE_ID to be <%s> but was <%s>", true, actual.getResourceId()); + } + + return this; + } + + public PropertiesRowAssert isEmpty() { + isNotNull(); + + if (!Objects.equals(actual.getEmpty(), TRUE)) { + failWithMessage("Expected PropertiesRow to have column IS_EMPTY to be <%s> but was <%s>", true, actual.getEmpty()); + } + if (actual.getTextValue() != null) { + failWithMessage("Expected PropertiesRow to have column TEXT_VALUE to be null but was <%s>", actual.getTextValue()); + } + if (actual.getClobValue() != null) { + failWithMessage("Expected PropertiesRow to have column CLOB_VALUE to be null but was <%s>", actual.getClobValue()); + } + + return this; + } + + public PropertiesRowAssert hasTextValue(String expected) { + isNotNull(); + + if (!Objects.equals(actual.getTextValue(), requireNonNull(expected))) { + failWithMessage("Expected PropertiesRow to have column TEXT_VALUE to be <%s> but was <%s>", expected, actual.getTextValue()); + } + if (actual.getClobValue() != null) { + failWithMessage("Expected PropertiesRow to have column CLOB_VALUE to be null but was <%s>", actual.getClobValue()); + } + if (!Objects.equals(actual.getEmpty(), FALSE)) { + failWithMessage("Expected PropertiesRow to have column IS_EMPTY to be <%s> but was <%s>", false, actual.getEmpty()); + } + + return this; + } + + public PropertiesRowAssert hasClobValue(String expected) { + isNotNull(); + + if (!Objects.equals(actual.getClobValue(), requireNonNull(expected))) { + failWithMessage("Expected PropertiesRow to have column CLOB_VALUE to be <%s> but was <%s>", true, actual.getClobValue()); + } + if (actual.getTextValue() != null) { + failWithMessage("Expected PropertiesRow to have column TEXT_VALUE to be null but was <%s>", actual.getTextValue()); + } + if (!Objects.equals(actual.getEmpty(), FALSE)) { + failWithMessage("Expected PropertiesRow to have column IS_EMPTY to be <%s> but was <%s>", false, actual.getEmpty()); + } + + return this; + } + + public PropertiesRowAssert hasCreatedAt(long expected) { + isNotNull(); + + if (!Objects.equals(actual.getCreatedAt(), expected)) { + failWithMessage("Expected PropertiesRow to have column CREATED_AT to be <%s> but was <%s>", expected, actual.getCreatedAt()); + } + + return this; + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/property/PropertyDbTester.java b/sonar-db/src/test/java/org/sonar/db/property/PropertyDbTester.java index bbef4a057f3..d43e8d08a24 100644 --- a/sonar-db/src/test/java/org/sonar/db/property/PropertyDbTester.java +++ b/sonar-db/src/test/java/org/sonar/db/property/PropertyDbTester.java @@ -46,7 +46,7 @@ public class PropertyDbTester { } public PropertyDto insertProperty(PropertyDto property) { - dbClient.propertiesDao().insertProperty(dbSession, property); + dbClient.propertiesDao().saveProperty(dbSession, property); db.commit(); return property; @@ -58,7 +58,7 @@ public class PropertyDbTester { public void insertProperties(List<PropertyDto> properties) { for (PropertyDto propertyDto : properties) { - dbClient.propertiesDao().insertProperty(dbSession, propertyDto); + dbClient.propertiesDao().saveProperty(dbSession, propertyDto); } dbSession.commit(); } diff --git a/sonar-db/src/test/java/org/sonar/db/property/PropertyDtoAssert.java b/sonar-db/src/test/java/org/sonar/db/property/PropertyDtoAssert.java new file mode 100644 index 00000000000..93f94e95a7b --- /dev/null +++ b/sonar-db/src/test/java/org/sonar/db/property/PropertyDtoAssert.java @@ -0,0 +1,93 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact 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.sonar.db.property; + +import java.util.Objects; +import javax.annotation.Nullable; +import org.assertj.core.api.AbstractAssert; + +import static java.util.Objects.requireNonNull; + +public class PropertyDtoAssert extends AbstractAssert<PropertyDtoAssert, PropertyDto> { + protected PropertyDtoAssert(@Nullable PropertyDto actual) { + super(actual, PropertyDtoAssert.class); + } + + public PropertyDtoAssert hasKey(String expected) { + isNotNull(); + + if (!Objects.equals(actual.getKey(), expected)) { + failWithMessage("Expected PropertyDto to have key to be <%s> but was <%s>", expected, actual.getKey()); + } + + return this; + } + + public PropertyDtoAssert hasNoUserId() { + isNotNull(); + + if (actual.getUserId() != null) { + failWithMessage("Expected PropertyDto to have userId to be null but was <%s>", actual.getUserId()); + } + + return this; + } + + public PropertyDtoAssert hasUserId(long expected) { + isNotNull(); + + if (!Objects.equals(actual.getUserId(), expected)) { + failWithMessage("Expected PropertyDto to have userId to be <%s> but was <%s>", true, actual.getUserId()); + } + + return this; + } + + public PropertyDtoAssert hasNoResourceId() { + isNotNull(); + + if (actual.getResourceId() != null) { + failWithMessage("Expected PropertyDto to have resourceId to be null but was <%s>", actual.getResourceId()); + } + + return this; + } + + public PropertyDtoAssert hasResourceId(long expected) { + isNotNull(); + + if (!Objects.equals(actual.getResourceId(), expected)) { + failWithMessage("Expected PropertyDto to have resourceId to be <%s> but was <%s>", true, actual.getResourceId()); + } + + return this; + } + + public PropertyDtoAssert hasValue(String expected) { + requireNonNull(expected); + isNotNull(); + + if (!Objects.equals(actual.getValue(), expected)) { + failWithMessage("Expected PropertyDto to have value to be <%s> but was <%s>", true, actual.getValue()); + } + + return this; + } +} diff --git a/sonar-db/src/test/java/org/sonar/db/qualitygate/ProjectQgateAssociationDaoTest.java b/sonar-db/src/test/java/org/sonar/db/qualitygate/ProjectQgateAssociationDaoTest.java index 5673fe776a3..220620323e0 100644 --- a/sonar-db/src/test/java/org/sonar/db/qualitygate/ProjectQgateAssociationDaoTest.java +++ b/sonar-db/src/test/java/org/sonar/db/qualitygate/ProjectQgateAssociationDaoTest.java @@ -109,7 +109,7 @@ public class ProjectQgateAssociationDaoTest { } private void associateProjectToQualityGate(long componentId, long qualityGateId) { - dbClient.propertiesDao().insertProperty(dbSession, new PropertyDto() + dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto() .setKey("sonar.qualitygate") .setResourceId(componentId) .setValue(String.valueOf(qualityGateId))); diff --git a/sonar-db/src/test/java/org/sonar/db/user/UserDaoTest.java b/sonar-db/src/test/java/org/sonar/db/user/UserDaoTest.java index aa2458da8aa..6e5a916033c 100644 --- a/sonar-db/src/test/java/org/sonar/db/user/UserDaoTest.java +++ b/sonar-db/src/test/java/org/sonar/db/user/UserDaoTest.java @@ -525,13 +525,13 @@ public class UserDaoTest { private PropertyDto insertProperty(UserDto user) { PropertyDto dto = new PropertyDto().setKey(randomAlphanumeric(100)).setUserId(user.getId()); - dbClient.propertiesDao().insertProperty(session, dto); + dbClient.propertiesDao().saveProperty(session, dto); return dto; } private PropertyDto insertProperty(String key, String value, long componentId) { PropertyDto dto = new PropertyDto().setKey(key).setValue(value).setResourceId(componentId); - dbClient.propertiesDao().insertProperty(session, dto); + dbClient.propertiesDao().saveProperty(session, dto); return dto; } diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete-result.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete-result.xml deleted file mode 100644 index ef4ec2a18b2..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete-result.xml +++ /dev/null @@ -1,14 +0,0 @@ -<dataset> - - <!-- global --> - <!--<properties id="1" prop_key="global.key" text_value="global" resource_id="[null]" user_id="[null]"/>--> - - <!-- project --> - <properties id="2" prop_key="project.key" text_value="project" resource_id="10" user_id="[null]"/> - - <!-- user --> - <properties id="3" prop_key="user.key" text_value="user" resource_id="[null]" user_id="100"/> - - <!-- null value --> - <properties id="4" prop_key="null.value" text_value="not null" resource_id="[null]" user_id="[null]"/> -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete.xml deleted file mode 100644 index 5229a2b791a..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete.xml +++ /dev/null @@ -1,14 +0,0 @@ -<dataset> - - <!-- global --> - <properties id="1" prop_key="global.key" text_value="global" resource_id="[null]" user_id="[null]"/> - - <!-- project --> - <properties id="2" prop_key="project.key" text_value="project" resource_id="10" user_id="[null]"/> - - <!-- user --> - <properties id="3" prop_key="user.key" text_value="user" resource_id="[null]" user_id="100"/> - - <!-- null value --> - <properties id="4" prop_key="null.value" text_value="not null" resource_id="[null]" user_id="[null]"/> -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteAllProperties-result.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteAllProperties-result.xml deleted file mode 100644 index ba4619fbedd..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteAllProperties-result.xml +++ /dev/null @@ -1,15 +0,0 @@ -<dataset> - - <!-- global --> - <!-- <properties id="1" prop_key="to_be_deleted" text_value="new_global" resource_id="[null]" user_id="[null]"/> --> - <properties id="2" prop_key="global.key" text_value="new_global" resource_id="[null]" user_id="[null]"/> - - <!-- project --> - <!-- <properties id="3" prop_key="to_be_deleted" text_value="new_project" resource_id="10" user_id="[null]"/> --> - <properties id="4" prop_key="project.key" text_value="new_project" resource_id="10" user_id="[null]"/> - - <!-- user --> - <!-- <properties id="5" prop_key="to_be_deleted" text_value="new_user" resource_id="[null]" user_id="100"/> --> - <properties id="6" prop_key="user.key" text_value="new_user" resource_id="[null]" user_id="100"/> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteAllProperties.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteAllProperties.xml deleted file mode 100644 index 0953b0ecd9f..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteAllProperties.xml +++ /dev/null @@ -1,15 +0,0 @@ -<dataset> - - <!-- global --> - <properties id="1" prop_key="to_be_deleted" text_value="new_global" resource_id="[null]" user_id="[null]"/> - <properties id="2" prop_key="global.key" text_value="new_global" resource_id="[null]" user_id="[null]"/> - - <!-- project --> - <properties id="3" prop_key="to_be_deleted" text_value="new_project" resource_id="10" user_id="[null]"/> - <properties id="4" prop_key="project.key" text_value="new_project" resource_id="10" user_id="[null]"/> - - <!-- user --> - <properties id="5" prop_key="to_be_deleted" text_value="new_user" resource_id="[null]" user_id="100"/> - <properties id="6" prop_key="user.key" text_value="new_user" resource_id="[null]" user_id="100"/> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteGlobalProperties-result.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteGlobalProperties-result.xml deleted file mode 100644 index a5cfed3378b..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteGlobalProperties-result.xml +++ /dev/null @@ -1,12 +0,0 @@ -<dataset> - - <!-- global --> - <!--<properties id="1" prop_key="global.key" text_value="new_global" resource_id="[null]" user_id="[null]"/>--> - - <!-- project --> - <properties id="2" prop_key="project.key" text_value="new_project" resource_id="10" user_id="[null]"/> - - <!-- user --> - <properties id="3" prop_key="user.key" text_value="new_user" resource_id="[null]" user_id="100"/> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteGlobalProperties.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteGlobalProperties.xml deleted file mode 100644 index 3e5eb87705c..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteGlobalProperties.xml +++ /dev/null @@ -1,12 +0,0 @@ -<dataset> - - <!-- global --> - <properties id="1" prop_key="global.key" text_value="new_global" resource_id="[null]" user_id="[null]"/> - - <!-- project --> - <properties id="2" prop_key="project.key" text_value="new_project" resource_id="10" user_id="[null]"/> - - <!-- user --> - <properties id="3" prop_key="user.key" text_value="new_user" resource_id="[null]" user_id="100"/> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteGlobalProperty-result.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteGlobalProperty-result.xml deleted file mode 100644 index 0428139feb6..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteGlobalProperty-result.xml +++ /dev/null @@ -1,13 +0,0 @@ -<dataset> - - <!-- global --> - <properties id="1" prop_key="global.key" text_value="new_global" resource_id="[null]" user_id="[null]"/> - <!--<properties id="2" prop_key="to_be_deleted" text_value="xxx" resource_id="[null]" user_id="[null]"/>--> - - <!-- project --> - <properties id="3" prop_key="to_be_deleted" text_value="new_project" resource_id="10" user_id="[null]"/> - - <!-- user --> - <properties id="4" prop_key="user.key" text_value="new_user" resource_id="[null]" user_id="100"/> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteGlobalProperty.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteGlobalProperty.xml deleted file mode 100644 index aaf0fd642d3..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/deleteGlobalProperty.xml +++ /dev/null @@ -1,13 +0,0 @@ -<dataset> - - <!-- global --> - <properties id="1" prop_key="global.key" text_value="new_global" resource_id="[null]" user_id="[null]"/> - <properties id="2" prop_key="to_be_deleted" text_value="xxx" resource_id="[null]" user_id="[null]"/> - - <!-- project - do not delete this project property that has the same key --> - <properties id="3" prop_key="to_be_deleted" text_value="new_project" resource_id="10" user_id="[null]"/> - - <!-- user --> - <properties id="4" prop_key="user.key" text_value="new_user" resource_id="[null]" user_id="100"/> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete_project_properties-result.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete_project_properties-result.xml deleted file mode 100644 index 97b8b6f02b3..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete_project_properties-result.xml +++ /dev/null @@ -1,12 +0,0 @@ -<dataset> - - <!--<properties id="1" prop_key="sonar.profile.java" text_value="Sonar Way" resource_id="1" user_id="[null]"/>--> - <!--<properties id="2" prop_key="sonar.profile.java" text_value="Sonar Way" resource_id="2" user_id="[null]"/>--> - - <properties id="3" prop_key="sonar.profile.java" text_value="Sonar Way" resource_id="[null]" user_id="[null]"/> - - <properties id="4" prop_key="sonar.profile.js" text_value="Sonar Way" resource_id="1" user_id="[null]"/> - <properties id="5" prop_key="sonar.profile.js" text_value="Sonar Way" resource_id="2" user_id="[null]"/> - <properties id="6" prop_key="sonar.profile.js" text_value="Sonar Way" resource_id="[null]" user_id="[null]"/> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete_project_properties.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete_project_properties.xml deleted file mode 100644 index 4e07f27e283..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete_project_properties.xml +++ /dev/null @@ -1,13 +0,0 @@ -<dataset> - - <properties id="1" prop_key="sonar.profile.java" text_value="Sonar Way" resource_id="1" user_id="[null]"/> - <properties id="2" prop_key="sonar.profile.java" text_value="Sonar Way" resource_id="2" user_id="[null]"/> - - <properties id="3" prop_key="sonar.profile.java" text_value="Sonar Way" resource_id="[null]" user_id="[null]"/> - - <properties id="4" prop_key="sonar.profile.js" text_value="Sonar Way" resource_id="1" user_id="[null]"/> - <properties id="5" prop_key="sonar.profile.js" text_value="Sonar Way" resource_id="2" user_id="[null]"/> - <properties id="6" prop_key="sonar.profile.js" text_value="Sonar Way" resource_id="[null]" user_id="[null]"/> - - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete_project_property-result.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete_project_property-result.xml deleted file mode 100644 index 0305f9f545c..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete_project_property-result.xml +++ /dev/null @@ -1,55 +0,0 @@ -<dataset> - - <!-- global --> - <properties id="1" - prop_key="global.one" - text_value="one" - resource_id="[null]" - user_id="[null]"/> - <properties id="2" - prop_key="global.two" - text_value="two" - resource_id="[null]" - user_id="[null]"/> - - <!-- struts --> - <!--<properties id="3" prop_key="struts.one" text_value="one" resource_id="10" user_id="[null]"/>--> - - <!-- commons --> - <properties id="4" - prop_key="commonslang.one" - text_value="two" - resource_id="11" - user_id="[null]"/> - - <!-- user --> - <properties id="5" - prop_key="user.one" - text_value="one" - resource_id="[null]" - user_id="100"/> - <properties id="6" - prop_key="user.two" - text_value="two" - resource_id="10" - user_id="100"/> - - <properties id="7" - prop_key="commonslang.one" - text_value="one" - resource_id="12" - user_id="[null]"/> - - <projects uuid="A" - uuid_path="NOT_USED" - kee="org.struts:struts" - id="10"/> - <projects uuid="B" - uuid_path="NOT_USED" - kee="org.apache:commons-lang" - id="11"/> - <projects uuid="C" - uuid_path="NOT_USED" - kee="other" - id="12"/> -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete_project_property.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete_project_property.xml deleted file mode 100644 index 4c532602cf0..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/delete_project_property.xml +++ /dev/null @@ -1,62 +0,0 @@ -<dataset> - - <!-- global --> - <properties id="1" - prop_key="global.one" - text_value="one" - resource_id="[null]" - user_id="[null]"/> - <properties id="2" - prop_key="global.two" - text_value="two" - resource_id="[null]" - user_id="[null]"/> - - <!-- struts --> - <properties id="3" - prop_key="struts.one" - text_value="one" - resource_id="10" - user_id="[null]"/> - - <!-- commons --> - <properties id="4" - prop_key="commonslang.one" - text_value="two" - resource_id="11" - user_id="[null]"/> - - <!-- user --> - <properties id="5" - prop_key="user.one" - text_value="one" - resource_id="[null]" - user_id="100"/> - <properties id="6" - prop_key="user.two" - text_value="two" - resource_id="10" - user_id="100"/> - - <properties id="7" - prop_key="commonslang.one" - text_value="one" - resource_id="12" - user_id="[null]"/> - - <projects uuid="A" - uuid_path="NOT_USED" - root_uuid="A" - kee="org.struts:struts" - id="10"/> - <projects uuid="B" - uuid_path="NOT_USED" - root_uuid="B" - kee="org.apache:commons-lang" - id="11"/> - <projects uuid="C" - uuid_path="NOT_USED" - root_uuid="C" - kee="other" - id="12"/> -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/insert-result.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/insert-result.xml deleted file mode 100644 index 3e5eb87705c..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/insert-result.xml +++ /dev/null @@ -1,12 +0,0 @@ -<dataset> - - <!-- global --> - <properties id="1" prop_key="global.key" text_value="new_global" resource_id="[null]" user_id="[null]"/> - - <!-- project --> - <properties id="2" prop_key="project.key" text_value="new_project" resource_id="10" user_id="[null]"/> - - <!-- user --> - <properties id="3" prop_key="user.key" text_value="new_user" resource_id="[null]" user_id="100"/> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/insert.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/insert.xml deleted file mode 100644 index 5ed00ba028b..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/insert.xml +++ /dev/null @@ -1 +0,0 @@ -<dataset></dataset>
\ No newline at end of file diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/insertGlobalProperties-result.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/insertGlobalProperties-result.xml deleted file mode 100644 index 5594180c370..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/insertGlobalProperties-result.xml +++ /dev/null @@ -1,5 +0,0 @@ -<dataset> - - <properties prop_key="to_be_inserted" text_value="inserted" resource_id="[null]" user_id="[null]"/> - -</dataset>
\ No newline at end of file diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/insertGlobalProperties.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/insertGlobalProperties.xml deleted file mode 100644 index 871dedcb5e9..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/insertGlobalProperties.xml +++ /dev/null @@ -1,3 +0,0 @@ -<dataset> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/renamePropertyKey-result.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/renamePropertyKey-result.xml deleted file mode 100644 index 0877b0035fe..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/renamePropertyKey-result.xml +++ /dev/null @@ -1,6 +0,0 @@ -<dataset> - - <properties id="1" prop_key="foo" text_value="bar" resource_id="[null]" user_id="[null]"/> - <properties id="2" prop_key="sonar.license" text_value="the license" resource_id="[null]" user_id="[null]"/> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/renamePropertyKey.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/renamePropertyKey.xml deleted file mode 100644 index 6ab761e2c6f..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/renamePropertyKey.xml +++ /dev/null @@ -1,6 +0,0 @@ -<dataset> - - <properties id="1" prop_key="foo" text_value="bar" resource_id="[null]" user_id="[null]"/> - <properties id="2" prop_key="sonar.license.secured" text_value="the license" resource_id="[null]" user_id="[null]"/> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/selectProjectPropertiesByResourceId.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/selectProjectPropertiesByResourceId.xml deleted file mode 100644 index d420c9dadc4..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/selectProjectPropertiesByResourceId.xml +++ /dev/null @@ -1,59 +0,0 @@ -<dataset> - - <!-- global --> - <properties id="1" - prop_key="global.one" - text_value="one" - resource_id="[null]" - user_id="[null]"/> - <properties id="2" - prop_key="global.two" - text_value="two" - resource_id="[null]" - user_id="[null]"/> - - <!-- struts --> - <properties id="3" - prop_key="struts.one" - text_value="one" - resource_id="10" - user_id="[null]"/> - - <!-- commons --> - <properties id="4" - prop_key="commonslang.one" - text_value="two" - resource_id="11" - user_id="[null]"/> - - <!-- user --> - <properties id="5" - prop_key="user.one" - text_value="one" - resource_id="[null]" - user_id="100"/> - <properties id="6" - prop_key="user.two" - text_value="two" - resource_id="10" - user_id="[null]"/> - - <properties id="7" - prop_key="commonslang.one" - text_value="one" - resource_id="12" - user_id="[null]"/> - - <projects uuid="A" - uuid_path="NOT_USED" - kee="org.struts:struts" - id="10"/> - <projects uuid="B" - uuid_path="NOT_USED" - kee="org.apache:commons-lang" - id="11"/> - <projects uuid="C" - uuid_path="NOT_USED" - kee="other" - id="12"/> -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/select_by_query.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/select_by_query.xml deleted file mode 100644 index 2873d69a5bc..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/select_by_query.xml +++ /dev/null @@ -1,19 +0,0 @@ -<dataset> - - <!-- global --> - <properties id="1" prop_key="global.one" text_value="one" resource_id="[null]" user_id="[null]"/> - <properties id="2" prop_key="global.two" text_value="two" resource_id="[null]" user_id="[null]"/> - - <!-- struts --> - <properties id="3" prop_key="struts.one" text_value="one" resource_id="10" user_id="[null]"/> - - <!-- commons --> - <properties id="4" prop_key="commonslang.one" text_value="two" resource_id="11" user_id="[null]"/> - - <!-- user --> - <properties id="5" prop_key="user.one" text_value="one" resource_id="[null]" user_id="100"/> - <properties id="6" prop_key="user.two" text_value="two" resource_id="10" user_id="100"/> - - <properties id="7" prop_key="commonslang.one" text_value="one" resource_id="12" user_id="[null]"/> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/select_module_properties_tree.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/select_module_properties_tree.xml index 9c6b865eaa4..8b837110e6b 100644 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/select_module_properties_tree.xml +++ b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/select_module_properties_tree.xml @@ -3,52 +3,68 @@ <!-- global --> <properties id="1" prop_key="global.one" - text_value="one" resource_id="[null]" - user_id="[null]"/> + user_id="[null]" + is_empty="[false]" + text_value="one" + created_at="1555000"/> <properties id="2" prop_key="global.two" - text_value="two" resource_id="[null]" - user_id="[null]"/> + user_id="[null]" + is_empty="[false]" + text_value="two" + created_at="1555000"/> <!-- org.struts:struts --> <properties id="3" prop_key="struts.one" - text_value="one" resource_id="1" - user_id="[null]"/> + user_id="[null]" + is_empty="[false]" + text_value="one" + created_at="1555000"/> <!-- org.struts:struts-core --> <properties id="4" prop_key="core.one" - text_value="one" resource_id="2" - user_id="[null]"/> + user_id="[null]" + is_empty="[false]" + text_value="one" + created_at="1555000"/> <properties id="7" prop_key="core.two" - text_value="two" resource_id="2" - user_id="[null]"/> + user_id="[null]" + is_empty="[false]" + text_value="two" + created_at="1555000"/> <!-- org.struts:struts-data --> <properties id="8" prop_key="data.one" - text_value="one" resource_id="3" - user_id="[null]"/> + user_id="[null]" + is_empty="[false]" + text_value="one" + created_at="1555000"/> <!-- user --> <properties id="5" prop_key="user.one" - text_value="one" resource_id="[null]" - user_id="100"/> + user_id="100" + is_empty="[false]" + text_value="one" + created_at="1555000"/> <properties id="6" prop_key="user.two" - text_value="two" resource_id="1" - user_id="102"/> + user_id="102" + is_empty="[false]" + text_value="two" + created_at="1555000"/> <!-- root project --> diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/should_not_rename_if_same_key-result.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/should_not_rename_if_same_key-result.xml deleted file mode 100644 index b4fc11a8cdb..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/should_not_rename_if_same_key-result.xml +++ /dev/null @@ -1,5 +0,0 @@ -<dataset> - - <properties id="1" prop_key="foo" text_value="bar" resource_id="[null]" user_id="[null]"/> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/should_not_rename_if_same_key.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/should_not_rename_if_same_key.xml deleted file mode 100644 index b4fc11a8cdb..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/should_not_rename_if_same_key.xml +++ /dev/null @@ -1,5 +0,0 @@ -<dataset> - - <properties id="1" prop_key="foo" text_value="bar" resource_id="[null]" user_id="[null]"/> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/update-result.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/update-result.xml deleted file mode 100644 index c3268596de3..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/update-result.xml +++ /dev/null @@ -1,15 +0,0 @@ -<dataset> - - <!-- global --> - <properties id="1" prop_key="global.key" text_value="new_global" resource_id="[null]" user_id="[null]"/> - - <!-- project --> - <properties id="2" prop_key="project.key" text_value="new_project" resource_id="10" user_id="[null]"/> - - <!-- user --> - <properties id="3" prop_key="user.key" text_value="new_user" resource_id="[null]" user_id="100"/> - - <!-- null value --> - <properties id="4" prop_key="null.value" text_value="[null]" resource_id="[null]" user_id="[null]"/> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/update.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/update.xml deleted file mode 100644 index 5229a2b791a..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/update.xml +++ /dev/null @@ -1,14 +0,0 @@ -<dataset> - - <!-- global --> - <properties id="1" prop_key="global.key" text_value="global" resource_id="[null]" user_id="[null]"/> - - <!-- project --> - <properties id="2" prop_key="project.key" text_value="project" resource_id="10" user_id="[null]"/> - - <!-- user --> - <properties id="3" prop_key="user.key" text_value="user" resource_id="[null]" user_id="100"/> - - <!-- null value --> - <properties id="4" prop_key="null.value" text_value="not null" resource_id="[null]" user_id="[null]"/> -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/updateGlobalProperties-result.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/updateGlobalProperties-result.xml deleted file mode 100644 index 12033fdc629..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/updateGlobalProperties-result.xml +++ /dev/null @@ -1,5 +0,0 @@ -<dataset> - - <properties prop_key="to_be_updated" text_value="updated" resource_id="[null]" user_id="[null]"/> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/updateGlobalProperties.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/updateGlobalProperties.xml deleted file mode 100644 index 4616072f3d9..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/updateGlobalProperties.xml +++ /dev/null @@ -1,5 +0,0 @@ -<dataset> - - <properties id="1" prop_key="to_be_updated" text_value="old value" resource_id="[null]" user_id="[null]"/> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/updatePropertiesFromKeyAndValueToNewValue-result.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/updatePropertiesFromKeyAndValueToNewValue-result.xml deleted file mode 100644 index 194761a6b2d..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/updatePropertiesFromKeyAndValueToNewValue-result.xml +++ /dev/null @@ -1,9 +0,0 @@ -<dataset> - - <properties id="1" prop_key="sonar.profile.java" text_value="Default" resource_id="[null]" user_id="[null]"/> - <properties id="2" prop_key="sonar.profile.java" text_value="Default" resource_id="1" user_id="[null]"/> - - <properties id="3" prop_key="sonar.profile.js" text_value="Sonar Way" resource_id="[null]" user_id="[null]"/> - <properties id="4" prop_key="sonar.profile.js" text_value="Sonar Way" resource_id="2" user_id="[null]"/> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/updatePropertiesFromKeyAndValueToNewValue.xml b/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/updatePropertiesFromKeyAndValueToNewValue.xml deleted file mode 100644 index 5567744e146..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/property/PropertiesDaoTest/updatePropertiesFromKeyAndValueToNewValue.xml +++ /dev/null @@ -1,9 +0,0 @@ -<dataset> - - <properties id="1" prop_key="sonar.profile.java" text_value="Sonar Way" resource_id="[null]" user_id="[null]"/> - <properties id="2" prop_key="sonar.profile.java" text_value="Sonar Way" resource_id="1" user_id="[null]"/> - - <properties id="3" prop_key="sonar.profile.js" text_value="Sonar Way" resource_id="[null]" user_id="[null]"/> - <properties id="4" prop_key="sonar.profile.js" text_value="Sonar Way" resource_id="2" user_id="[null]"/> - -</dataset> diff --git a/sonar-db/src/test/resources/org/sonar/db/qualitygate/ProjectQgateAssociationDaoTest/shared.xml b/sonar-db/src/test/resources/org/sonar/db/qualitygate/ProjectQgateAssociationDaoTest/shared.xml index e37eb2643ea..431aafa0198 100644 --- a/sonar-db/src/test/resources/org/sonar/db/qualitygate/ProjectQgateAssociationDaoTest/shared.xml +++ b/sonar-db/src/test/resources/org/sonar/db/qualitygate/ProjectQgateAssociationDaoTest/shared.xml @@ -185,18 +185,26 @@ <properties id="1" prop_key="sonar.qualitygate" resource_id="[null]" - text_value="43"/> + is_empty="[false]" + text_value="43" + created_at="1555000"/> <properties id="2" prop_key="sonar.qualitygate" resource_id="1" - text_value="42"/> + is_empty="[false]" + text_value="42" + created_at="1555000"/> <properties id="3" prop_key="sonar.qualitygate" resource_id="2" - text_value="42"/> + is_empty="[false]" + text_value="42" + created_at="1555000"/> <properties id="4" prop_key="sonar.qualitygate" resource_id="3" - text_value="42"/> + is_empty="[false]" + text_value="42" + created_at="1555000"/> </dataset> |