*/
public class DatabaseVersion implements BatchComponent, ServerComponent {
- public static final int LAST_VERSION = 510;
+ public static final int LAST_VERSION = 511;
public static enum Status {
UP_TO_DATE, REQUIRES_UPGRADE, REQUIRES_DOWNGRADE, FRESH_INSTALL
"perm_templates_users",
"perm_templates_groups",
"quality_gates",
+ "quality_gate_conditions",
"projects",
"project_links",
"project_measures",
*/
package org.sonar.core.persistence;
-import org.sonar.core.qualitygate.db.QualityGateMapper;
-
-import org.sonar.core.qualitygate.db.QualityGateDto;
import ch.qos.logback.classic.Level;
import com.google.common.io.Closeables;
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.sonar.core.properties.PropertyDto;
import org.sonar.core.purge.PurgeMapper;
import org.sonar.core.purge.PurgeableSnapshotDto;
+import org.sonar.core.qualitygate.db.QualityGateConditionDto;
+import org.sonar.core.qualitygate.db.QualityGateConditionMapper;
+import org.sonar.core.qualitygate.db.QualityGateDto;
+import org.sonar.core.qualitygate.db.QualityGateMapper;
import org.sonar.core.qualityprofile.db.*;
import org.sonar.core.resource.*;
import org.sonar.core.rule.*;
loadAlias(conf, "Property", PropertyDto.class);
loadAlias(conf, "PurgeableSnapshot", PurgeableSnapshotDto.class);
loadAlias(conf, "QualityGate", QualityGateDto.class);
+ loadAlias(conf, "QualityGateCondition", QualityGateConditionDto.class);
loadAlias(conf, "Resource", ResourceDto.class);
loadAlias(conf, "ResourceIndex", ResourceIndexDto.class);
loadAlias(conf, "ResourceSnapshot", ResourceSnapshotDto.class);
MeasureMapper.class, SnapshotDataMapper.class, SnapshotSourceMapper.class, ActionPlanMapper.class, ActionPlanStatsMapper.class,
NotificationQueueMapper.class, CharacteristicMapper.class, RuleTagMapper.class,
GroupMembershipMapper.class, QualityProfileMapper.class, ActiveRuleMapper.class,
- MeasureDataMapper.class, QualityGateMapper.class
+ MeasureDataMapper.class, QualityGateMapper.class, QualityGateConditionMapper.class
};
loadMappers(conf, mappers);
configureLogback(mappers);
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.core.qualitygate.db;
+
+import org.apache.ibatis.session.SqlSession;
+import org.sonar.core.persistence.MyBatis;
+
+import java.util.Collection;
+
+/**
+ * @since 4.3
+ */
+public class QualityGateConditionDao {
+
+ private final MyBatis myBatis;
+
+ public QualityGateConditionDao(MyBatis myBatis) {
+ this.myBatis = myBatis;
+ }
+
+ public void insert(QualityGateConditionDto newQualityGate) {
+ SqlSession session = myBatis.openSession();
+ try {
+ insert(newQualityGate, session);
+ session.commit();
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ public void insert(QualityGateConditionDto newQualityGate, SqlSession session) {
+ getMapper(session).insert(newQualityGate);
+ }
+
+ public Collection<QualityGateConditionDto> selectForQualityGate(long qGateId) {
+ SqlSession session = myBatis.openSession();
+ try {
+ return selectForQualityGate(qGateId, session);
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ public Collection<QualityGateConditionDto> selectForQualityGate(long qGateId, SqlSession session) {
+ return getMapper(session).selectForQualityGate(qGateId);
+ }
+
+ public QualityGateConditionDto selectById(long id) {
+ SqlSession session = myBatis.openSession();
+ try {
+ return selectById(id, session);
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ public QualityGateConditionDto selectById(long id, SqlSession session) {
+ return getMapper(session).selectById(id);
+ }
+
+ public void delete(QualityGateConditionDto qGate) {
+ SqlSession session = myBatis.openSession();
+ try {
+ delete(qGate, session);
+ session.commit();
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ public void delete(QualityGateConditionDto qGate, SqlSession session) {
+ getMapper(session).delete(qGate.getId());
+ }
+
+ public void update(QualityGateConditionDto qGate) {
+ SqlSession session = myBatis.openSession();
+ try {
+ update(qGate, session);
+ session.commit();
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ public void update(QualityGateConditionDto qGate, SqlSession session) {
+ getMapper(session).update(qGate);
+ }
+
+ private QualityGateConditionMapper getMapper(SqlSession session) {
+ return session.getMapper(QualityGateConditionMapper.class);
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.core.qualitygate.db;
+
+/**
+ * @since 4.3
+ */
+public class QualityGateConditionDto {
+
+ private long id;
+
+ private long qualityGateId;
+
+ private long metricId;
+
+ private int period;
+
+ private String operator;
+
+ private String warningThreshold;
+
+ private String errorThreshold;
+
+ public long getId() {
+ return id;
+ }
+
+ public QualityGateConditionDto setId(long id) {
+ this.id = id;
+ return this;
+ }
+
+ public long getQualityGateId() {
+ return qualityGateId;
+ }
+
+ public QualityGateConditionDto setQualityGateId(long qualityGateId) {
+ this.qualityGateId = qualityGateId;
+ return this;
+ }
+
+ public long getMetricId() {
+ return metricId;
+ }
+
+ public QualityGateConditionDto setMetricId(long metricId) {
+ this.metricId = metricId;
+ return this;
+ }
+
+ public int getPeriod() {
+ return period;
+ }
+
+ public QualityGateConditionDto setPeriod(int period) {
+ this.period = period;
+ return this;
+ }
+
+ public String getOperator() {
+ return operator;
+ }
+
+ public QualityGateConditionDto setOperator(String operator) {
+ this.operator = operator;
+ return this;
+ }
+
+ public String getWarningThreshold() {
+ return warningThreshold;
+ }
+
+ public QualityGateConditionDto setWarningThreshold(String warningThreshold) {
+ this.warningThreshold = warningThreshold;
+ return this;
+ }
+
+ public String getErrorThreshold() {
+ return errorThreshold;
+ }
+
+ public QualityGateConditionDto setErrorThreshold(String errorThreshold) {
+ this.errorThreshold = errorThreshold;
+ return this;
+ }
+}
--- /dev/null
+package org.sonar.core.qualitygate.db;
+
+import java.util.List;
+
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.
+ */
+public interface QualityGateConditionMapper {
+
+ void insert(QualityGateConditionDto newCondition);
+
+ List<QualityGateConditionDto> selectForQualityGate(long qGateId);
+
+ void update(QualityGateConditionDto newCondition);
+
+ QualityGateConditionDto selectById(long id);
+
+ void delete(long id);
+}
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('497');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('498');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('510');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('511');
INSERT INTO USERS(ID, LOGIN, NAME, EMAIL, CRYPTED_PASSWORD, SALT, CREATED_AT, UPDATED_AT, REMEMBER_TOKEN, REMEMBER_TOKEN_EXPIRES_AT) VALUES (1, 'admin', 'Administrator', '', 'a373a0e667abb2604c1fd571eb4ad47fe8cc0878', '48bc4b0d93179b5103fd3885ea9119498e9d161b', '2011-09-26 22:27:48.0', '2011-09-26 22:27:48.0', null, null);
ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 2;
"NAME" VARCHAR(100) NOT NULL,
);
+CREATE TABLE "QUALITY_GATE_CONDITIONS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "QGATE_ID" INTEGER,
+ "METRIC_ID" INTEGER,
+ "OPERATOR" VARCHAR(3),
+ "VALUE_ERROR" VARCHAR(64),
+ "VALUE_WARNING" VARCHAR(64),
+ "PERIOD" INTEGER,
+);
+
CREATE TABLE "PROPERTIES" (
"ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
"PROP_KEY" VARCHAR(512),
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="org.sonar.core.qualitygate.db.QualityGateConditionMapper">
+
+ <insert id="insert" parameterType="QualityGateCondition" keyColumn="id" useGeneratedKeys="true" keyProperty="id">
+ insert into quality_gate_conditions (qgate_id, metric_id, operator, value_error, value_warning, period)
+ values (#{qualityGateId}, #{metricId}, #{operator}, #{warningThreshold}, #{errorThreshold}, #{period})
+ </insert>
+
+ <sql id="conditionColumns">
+ qgate_id as qualityGateId, metric_id as metricId, operator, value_warning as warningThreshold, value_error as errorThreshold, period
+ </sql>
+
+ <select id="selectForQualityGate" resultType="QualityGateCondition" parameterType="long">
+ select <include refid="conditionColumns"/> from quality_gate_conditions where qgate_id=#{qGateId}
+ order by id asc
+ </select>
+
+ <select id="selectById" parameterType="long" resultType="QualityGateCondition">
+ select <include refid="conditionColumns"/> from quality_gate_conditions where id=#{id}
+ </select>
+
+ <update id="delete" parameterType="long">
+ delete from quality_gate_conditions where id=#{id}
+ </update>
+
+ <update id="update" parameterType="QualityGateCondition">
+ update quality_gate_conditions set
+ metric_id=#{metricId},
+ operator=#{operator},
+ value_warning=#{warningThreshold},
+ value_error=#{errorThreshold},
+ period=#{period}
+ where id=#{id}
+ </update>
+
+</mapper>
+
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.core.qualitygate.db;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.core.persistence.AbstractDaoTestCase;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class QualityGateConditionDaoTest extends AbstractDaoTestCase {
+
+ private static QualityGateConditionDao dao;
+
+ @Before
+ public void createDao() throws Exception {
+ dao = new QualityGateConditionDao(getMyBatis());
+ }
+
+ @Test
+ public void testInsert() throws Exception {
+ setupData("insert");
+ QualityGateConditionDto newCondition = new QualityGateConditionDto()
+ .setQualityGateId(1L).setMetricId(2L).setOperator(">").setWarningThreshold("10").setErrorThreshold("20").setPeriod(3);
+ dao.insert(newCondition);
+ checkTable("insert", "quality_gate_conditions", "name");
+ assertThat(newCondition.getId()).isNotNull();
+ }
+
+ @Test
+ public void testSelectForQualityGate() throws Exception {
+ setupData("selectForQualityGate");
+ assertThat(dao.selectForQualityGate(1L)).hasSize(3);
+ assertThat(dao.selectForQualityGate(2L)).hasSize(2);
+ }
+
+ @Test
+ public void testSelectById() throws Exception {
+ setupData("selectForQualityGate");
+ QualityGateConditionDto selectById = dao.selectById(1L);
+ assertThat(selectById).isNotNull();
+ assertThat(selectById.getId()).isNotNull();
+ assertThat(selectById.getMetricId()).isEqualTo(2L);
+ assertThat(selectById.getOperator()).isEqualTo("<");
+ assertThat(selectById.getPeriod()).isEqualTo(3);
+ assertThat(selectById.getQualityGateId()).isEqualTo(1L);
+ assertThat(selectById.getWarningThreshold()).isEqualTo("10");
+ assertThat(selectById.getErrorThreshold()).isEqualTo("20");
+ assertThat(dao.selectById(42L)).isNull();
+ }
+
+ @Test
+ public void testDelete() throws Exception {
+ setupData("selectForQualityGate");
+ dao.delete(new QualityGateConditionDto().setId(1L));
+ checkTable("delete", "quality_gate_conditions");
+ }
+
+ @Test
+ public void testUpdate() throws Exception {
+ setupData("selectForQualityGate");
+ dao.update(new QualityGateConditionDto().setId(1L).setMetricId(7L).setOperator(">").setPeriod(1).setWarningThreshold("50").setErrorThreshold("80"));
+ checkTable("update", "quality_gate_conditions");
+ }
+
+}
--- /dev/null
+<dataset>
+
+ <quality_gate_conditions id="2" qgate_id="1" metric_id="3" operator="<" value_warning="10" value_error="20" period="[null]" />
+ <quality_gate_conditions id="3" qgate_id="1" metric_id="4" operator="<" value_warning="10" value_error="[null]" period="1" />
+ <quality_gate_conditions id="4" qgate_id="2" metric_id="5" operator="<" value_warning="[null]" value_error="20" period="3" />
+ <quality_gate_conditions id="5" qgate_id="2" metric_id="6" operator="<" value_warning="[null]" value_error="20" period="[null]" />
+
+</dataset>
--- /dev/null
+<dataset>
+
+ <quality_gate_conditions id="1" qgate_id="1" metric_id="2" operator="<" value_warning="10" value_error="20" period="3" />
+
+</dataset>
--- /dev/null
+<dataset>
+
+</dataset>
--- /dev/null
+<dataset>
+
+ <quality_gate_conditions id="1" qgate_id="1" metric_id="2" operator="<" value_warning="10" value_error="20" period="3" />
+ <quality_gate_conditions id="2" qgate_id="1" metric_id="3" operator="<" value_warning="10" value_error="20" period="[null]" />
+ <quality_gate_conditions id="3" qgate_id="1" metric_id="4" operator="<" value_warning="10" value_error="[null]" period="1" />
+ <quality_gate_conditions id="4" qgate_id="2" metric_id="5" operator="<" value_warning="[null]" value_error="20" period="3" />
+ <quality_gate_conditions id="5" qgate_id="2" metric_id="6" operator="<" value_warning="[null]" value_error="20" period="[null]" />
+
+</dataset>
--- /dev/null
+<dataset>
+
+ <quality_gate_conditions id="1" qgate_id="1" metric_id="7" operator=">" value_warning="50" value_error="80" period="1" />
+ <quality_gate_conditions id="2" qgate_id="1" metric_id="3" operator="<" value_warning="10" value_error="20" period="[null]" />
+ <quality_gate_conditions id="3" qgate_id="1" metric_id="4" operator="<" value_warning="10" value_error="[null]" period="1" />
+ <quality_gate_conditions id="4" qgate_id="2" metric_id="5" operator="<" value_warning="[null]" value_error="20" period="3" />
+ <quality_gate_conditions id="5" qgate_id="2" metric_id="6" operator="<" value_warning="[null]" value_error="20" period="[null]" />
+
+</dataset>
import org.sonar.core.preview.PreviewCache;
import org.sonar.core.profiling.Profiling;
import org.sonar.core.purge.PurgeProfiler;
+import org.sonar.core.qualitygate.db.QualityGateConditionDao;
import org.sonar.core.qualitygate.db.QualityGateDao;
import org.sonar.core.resource.DefaultResourcePermissions;
import org.sonar.core.rule.DefaultRuleFinder;
// quality gates
servicesContainer.addSingleton(QualityGateDao.class);
+ servicesContainer.addSingleton(QualityGateConditionDao.class);
servicesContainer.addSingleton(QualityGates.class);
servicesContainer.addSingleton(QualityGatesWs.class);
import org.sonar.core.permission.GlobalPermissions;
import org.sonar.core.properties.PropertiesDao;
import org.sonar.core.properties.PropertyDto;
+import org.sonar.core.qualitygate.db.QualityGateConditionDao;
+import org.sonar.core.qualitygate.db.QualityGateConditionDto;
import org.sonar.core.qualitygate.db.QualityGateDao;
import org.sonar.core.qualitygate.db.QualityGateDto;
import org.sonar.server.exceptions.BadRequestException;
private final QualityGateDao dao;
+ private final QualityGateConditionDao conditionDao;
+
private final PropertiesDao propertiesDao;
- public QualityGates(QualityGateDao dao, PropertiesDao propertiesDao) {
+ public QualityGates(QualityGateDao dao, QualityGateConditionDao conditionDao, PropertiesDao propertiesDao) {
this.dao = dao;
+ this.conditionDao = conditionDao;
this.propertiesDao = propertiesDao;
}
}
}
+ public QualityGateConditionDto createCondition(long qGateId, long metricId, String operator,
+ @Nullable String warningThreshold, @Nullable String errorThreshold, @Nullable Integer period) {
+ return null;
+ }
+
private boolean isDefault(QualityGateDto qGate) {
return qGate.getName().equals(getDefaultName());
}
--- /dev/null
+#
+# SonarQube, open source software quality management tool.
+# Copyright (C) 2008-2013 SonarSource
+# mailto:contact AT sonarsource DOT com
+#
+# SonarQube 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.
+#
+# SonarQube 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.
+#
+class CreateQualityGateConditions < ActiveRecord::Migration
+
+ def self.up
+ create_table :quality_gate_conditions do |t|
+ t.column :qgate_id, :integer
+ t.column :metric_id, :integer
+ t.column :period, :integer, :null => true
+ t.column :operator, :string, :limit => 3, :null => true
+ t.column :value_error, :string, :limit => 64, :null => true
+ t.column :value_warning, :string, :limit => 64, :null => true
+ end
+ end
+
+end
*/
package org.sonar.server.qualitygate;
-import org.sonar.core.properties.PropertyDto;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Matchers;
-import org.sonar.server.exceptions.NotFoundException;
-import org.sonar.core.properties.PropertiesDao;
-import org.sonar.server.exceptions.ForbiddenException;
-import org.sonar.server.exceptions.UnauthorizedException;
-import org.sonar.server.user.UserSessionTestUtils;
-import org.sonar.core.permission.GlobalPermissions;
-import org.sonar.server.user.MockUserSession;
-import org.sonar.server.user.UserSession;
import com.google.common.collect.Lists;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
+import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.core.properties.PropertiesDao;
+import org.sonar.core.properties.PropertyDto;
+import org.sonar.core.qualitygate.db.QualityGateConditionDao;
import org.sonar.core.qualitygate.db.QualityGateDao;
import org.sonar.core.qualitygate.db.QualityGateDto;
import org.sonar.server.exceptions.BadRequestException;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.exceptions.UnauthorizedException;
+import org.sonar.server.user.MockUserSession;
+import org.sonar.server.user.UserSession;
+import org.sonar.server.user.UserSessionTestUtils;
import java.util.List;
-import static org.fest.assertions.Assertions.*;
+import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@Mock
private QualityGateDao dao;
+ @Mock
+ private QualityGateConditionDao conditionDao;
+
@Mock
private PropertiesDao propertiesDao;
@Before
public void initialize() {
- qGates = new QualityGates(dao, propertiesDao);
+ qGates = new QualityGates(dao, conditionDao, propertiesDao);
UserSessionTestUtils.setUserSession(authorizedUserSession);
}