summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@gmail.com>2013-06-11 10:27:42 +0200
committerJulien Lancelot <julien.lancelot@gmail.com>2013-06-11 10:27:42 +0200
commita384ced603ce00b9f6f9590d345808dd933e730b (patch)
tree7cfc9d4a84b7489648a6c0706ff63c9ac3528dfb
parent39dd68b5054ef5e3c136efad0ad4c98d263a498a (diff)
downloadsonarqube-a384ced603ce00b9f6f9590d345808dd933e730b.tar.gz
sonarqube-a384ced603ce00b9f6f9590d345808dd933e730b.zip
SONAR-4383 Add IssueFilters db creation script and DAO
-rw-r--r--sonar-core/src/main/java/org/sonar/core/issue/db/IssueFilterDao.java97
-rw-r--r--sonar-core/src/main/java/org/sonar/core/issue/db/IssueFilterDto.java111
-rw-r--r--sonar-core/src/main/java/org/sonar/core/issue/db/IssueFilterMapper.java41
-rw-r--r--sonar-core/src/main/java/org/sonar/core/persistence/DaoUtils.java1
-rw-r--r--sonar-core/src/main/java/org/sonar/core/persistence/DatabaseUtils.java2
-rw-r--r--sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java2
-rw-r--r--sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java12
-rw-r--r--sonar-core/src/main/resources/org/sonar/core/issue/db/IssueChangeMapper.xml20
-rw-r--r--sonar-core/src/main/resources/org/sonar/core/issue/db/IssueFilterMapper.xml57
-rw-r--r--sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql2
-rw-r--r--sonar-core/src/main/resources/org/sonar/core/persistence/schema-h2.ddl22
-rw-r--r--sonar-core/src/test/java/org/sonar/core/issue/db/IssueFilterDaoTest.java103
-rw-r--r--sonar-core/src/test/java/org/sonar/core/measure/MeasureFilterDaoTest.java1
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/issue/db/IssueFilterDaoTest/shared.xml23
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/issue/db/IssueFilterDaoTest/should_delete-result.xml13
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/issue/db/IssueFilterDaoTest/should_insert-result.xml34
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/issue/db/IssueFilterDaoTest/should_select_by_user.xml33
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/issue/db/IssueFilterDaoTest/should_update-result.xml23
-rw-r--r--sonar-server/src/main/java/org/sonar/server/issue/IssueFilterService.java33
-rw-r--r--sonar-server/src/main/java/org/sonar/server/platform/Platform.java1
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/db/migrate/410_create_issue_filters.rb38
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/db/migrate/411_create_issue_filter_favourites.rb37
22 files changed, 679 insertions, 27 deletions
diff --git a/sonar-core/src/main/java/org/sonar/core/issue/db/IssueFilterDao.java b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueFilterDao.java
new file mode 100644
index 00000000000..37d9790a9e8
--- /dev/null
+++ b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueFilterDao.java
@@ -0,0 +1,97 @@
+/*
+ * 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.issue.db;
+
+import org.apache.ibatis.session.SqlSession;
+import org.sonar.api.BatchComponent;
+import org.sonar.api.ServerComponent;
+import org.sonar.core.persistence.MyBatis;
+
+import javax.annotation.CheckForNull;
+
+import java.util.List;
+
+/**
+ * @since 3.6
+ */
+public class IssueFilterDao implements BatchComponent, ServerComponent {
+
+ private final MyBatis mybatis;
+
+ public IssueFilterDao(MyBatis mybatis) {
+ this.mybatis = mybatis;
+ }
+
+ @CheckForNull
+ public IssueFilterDto selectById(Integer id) {
+ SqlSession session = mybatis.openSession();
+ try {
+ session.getMapper(IssueFilterMapper.class);
+ return getMapper(session).selectById(id);
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ public List<IssueFilterDto> selectByUser(Integer userId) {
+ SqlSession session = mybatis.openSession();
+ try {
+ session.getMapper(IssueFilterMapper.class);
+ return getMapper(session).selectByUser(userId);
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ public void insert(IssueFilterDto filter) {
+ SqlSession session = mybatis.openSession();
+ try {
+ getMapper(session).insert(filter);
+ session.commit();
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ public void update(IssueFilterDto filter) {
+ SqlSession session = mybatis.openSession();
+ try {
+ getMapper(session).update(filter);
+ session.commit();
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ public void delete(Integer id) {
+ SqlSession session = mybatis.openSession();
+ try {
+ getMapper(session).delete(id);
+ session.commit();
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ private IssueFilterMapper getMapper(SqlSession session) {
+ return session.getMapper(IssueFilterMapper.class);
+ }
+}
diff --git a/sonar-core/src/main/java/org/sonar/core/issue/db/IssueFilterDto.java b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueFilterDto.java
new file mode 100644
index 00000000000..1e4c59c4857
--- /dev/null
+++ b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueFilterDto.java
@@ -0,0 +1,111 @@
+/*
+ * 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.issue.db;
+
+import javax.annotation.Nullable;
+
+import java.util.Date;
+
+/**
+ * @since 3.6
+ */
+public class IssueFilterDto {
+
+ private Long id;
+ private String name;
+ private Long userId;
+ private Boolean shared;
+ private String description;
+ private String data;
+ private Date createdAt;
+ private Date updatedAt;
+
+ public Long getId() {
+ return id;
+ }
+
+ public IssueFilterDto setId(Long id) {
+ this.id = id;
+ return this;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public IssueFilterDto setName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public Long getUserId() {
+ return userId;
+ }
+
+ public IssueFilterDto setUserId(@Nullable Long userId) {
+ this.userId = userId;
+ return this;
+ }
+
+ public Boolean isShared() {
+ return shared;
+ }
+
+ public IssueFilterDto setShared(@Nullable Boolean shared) {
+ this.shared = shared;
+ return this;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public IssueFilterDto setDescription(@Nullable String description) {
+ this.description = description;
+ return this;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public IssueFilterDto setData(String data) {
+ this.data = data;
+ return this;
+ }
+
+ public Date getCreatedAt() {
+ return createdAt;
+ }
+
+ public IssueFilterDto setCreatedAt(Date createdAt) {
+ this.createdAt = createdAt;
+ return this;
+ }
+
+ public Date getUpdatedAt() {
+ return updatedAt;
+ }
+
+ public IssueFilterDto setUpdatedAt(Date updatedAt) {
+ this.updatedAt = updatedAt;
+ return this;
+ }
+}
diff --git a/sonar-core/src/main/java/org/sonar/core/issue/db/IssueFilterMapper.java b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueFilterMapper.java
new file mode 100644
index 00000000000..9bf819d11cd
--- /dev/null
+++ b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueFilterMapper.java
@@ -0,0 +1,41 @@
+/*
+ * 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.issue.db;
+
+import javax.annotation.CheckForNull;
+
+import java.util.List;
+
+/**
+ * @since 3.6
+ */
+public interface IssueFilterMapper {
+
+ @CheckForNull
+ IssueFilterDto selectById(Integer id);
+
+ List<IssueFilterDto> selectByUser(Integer userId);
+
+ void insert(IssueFilterDto filter);
+
+ void update(IssueFilterDto filter);
+
+ void delete(Integer id);
+}
diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/DaoUtils.java b/sonar-core/src/main/java/org/sonar/core/persistence/DaoUtils.java
index 33fa7b7708a..db936c44976 100644
--- a/sonar-core/src/main/java/org/sonar/core/persistence/DaoUtils.java
+++ b/sonar-core/src/main/java/org/sonar/core/persistence/DaoUtils.java
@@ -59,6 +59,7 @@ public final class DaoUtils {
IssueDao.class,
IssueStatsDao.class,
IssueChangeDao.class,
+ IssueFilterDao.class,
LoadedTemplateDao.class,
MeasureFilterDao.class,
PropertiesDao.class,
diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseUtils.java b/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseUtils.java
index 4d684fc9e74..d981d427536 100644
--- a/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseUtils.java
+++ b/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseUtils.java
@@ -62,6 +62,8 @@ public final class DatabaseUtils {
"group_roles",
"issues",
"issue_changes",
+ "issue_filters",
+ "issue_filter_favourites",
"loaded_templates",
"manual_measures",
"measure_data",
diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java b/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java
index e70f13887bd..f060ae68e59 100644
--- a/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java
+++ b/sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java
@@ -32,7 +32,7 @@ import java.util.List;
*/
public class DatabaseVersion implements BatchComponent, ServerComponent {
- public static final int LAST_VERSION = 403;
+ public static final int LAST_VERSION = 411;
public static enum Status {
UP_TO_DATE, REQUIRES_UPGRADE, REQUIRES_DOWNGRADE, FRESH_INSTALL
diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java b/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java
index 41d9eb9200a..90b83920742 100644
--- a/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java
+++ b/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java
@@ -115,22 +115,24 @@ public class MyBatis implements BatchComponent, ServerComponent {
loadAlias(conf, "MeasureData", MeasureData.class);
loadAlias(conf, "Issue", IssueDto.class);
loadAlias(conf, "IssueChange", IssueChangeDto.class);
+ loadAlias(conf, "IssueFilter", IssueFilterDto.class);
loadAlias(conf, "SnapshotData", SnapshotDataDto.class);
loadAlias(conf, "ActionPlanIssue", ActionPlanDto.class);
loadAlias(conf, "ActionPlanStats", ActionPlanStatsDto.class);
+ // AuthorizationMapper has to be loaded before IssueMapper because this last one used it
+ loadMapper(conf, "org.sonar.core.user.AuthorizationMapper");
+ // ResourceMapper has to be loaded before IssueMapper because this last one used it
+ loadMapper(conf, ResourceMapper.class);
+
Class<?>[] mappers = {ActiveDashboardMapper.class, AuthorMapper.class, DashboardMapper.class,
DependencyMapper.class, DuplicationMapper.class, GraphDtoMapper.class,
- IssueMapper.class, IssueStatsMapper.class, IssueChangeMapper.class,
+ IssueMapper.class, IssueStatsMapper.class, IssueChangeMapper.class, IssueFilterMapper.class,
LoadedTemplateMapper.class, MeasureFilterMapper.class, PropertiesMapper.class, PurgeMapper.class, ResourceKeyUpdaterMapper.class, ResourceIndexerMapper.class,
ResourceSnapshotMapper.class, RoleMapper.class, RuleMapper.class, SchemaMigrationMapper.class,
SemaphoreMapper.class, UserMapper.class, WidgetMapper.class, WidgetPropertyMapper.class, MeasureMapper.class, SnapshotDataMapper.class,
SnapshotSourceMapper.class, ActionPlanMapper.class, ActionPlanStatsMapper.class
};
- // AuthorizationMapper has to be loaded before IssueMapper because this last one used it
- loadMapper(conf, "org.sonar.core.user.AuthorizationMapper");
- // ResourceMapper has to be loaded before IssueMapper because this last one used it
- loadMapper(conf, ResourceMapper.class);
loadMappers(conf, mappers);
configureLogback(mappers);
diff --git a/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueChangeMapper.xml b/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueChangeMapper.xml
index 83cd957bd93..0d1c57ee136 100644
--- a/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueChangeMapper.xml
+++ b/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueChangeMapper.xml
@@ -1,25 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<!--
- ~ 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.
- -->
-
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mappei.dtd">
<mapper namespace="org.sonar.core.issue.db.IssueChangeMapper">
diff --git a/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueFilterMapper.xml b/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueFilterMapper.xml
new file mode 100644
index 00000000000..d14bec6f23c
--- /dev/null
+++ b/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueFilterMapper.xml
@@ -0,0 +1,57 @@
+<?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.issue.db.IssueFilterMapper">
+
+ <sql id="issueFilterColumns">
+ if.id,
+ if.name as name,
+ if.user_id as userId,
+ if.shared as shared,
+ if.description as description,
+ if.data as data,
+ if.created_at as createdAt,
+ if.updated_at as updatedAt
+ </sql>
+
+ <select id="selectById" parameterType="int" resultType="IssueFilter">
+ select <include refid="issueFilterColumns"/>
+ from issue_filters if WHERE id=#{id}
+ </select>
+
+ <select id="selectByUser" parameterType="int" resultType="IssueFilter">
+ select <include refid="issueFilterColumns"/>
+ from issue_filters if WHERE user_id=#{userId}
+ </select>
+
+ <insert id="insert" parameterType="IssueFilter" useGeneratedKeys="true" keyProperty="id">
+ INSERT INTO issue_filters (name, user_id, shared, description, data, created_at, updated_at)
+ VALUES (#{name}, #{userId}, #{shared}, #{description}, #{data}, #{createdAt}, #{updatedAt})
+ </insert>
+
+ <!-- Oracle -->
+ <insert id="insert" databaseId="oracle" parameterType="IssueFilter" keyColumn="id" useGeneratedKeys="true" keyProperty="id">
+ <selectKey order="BEFORE" resultType="Long" keyProperty="id">
+ select issue_filters_seq.NEXTVAL from DUAL
+ </selectKey>
+ INSERT INTO issue_filters (id, name, user_id, shared, description, data, created_at, updated_at)
+ VALUES (#{id}, #{name}, #{userId}, #{shared}, #{description}, #{data}, #{createdAt}, #{updatedAt})
+ </insert>
+
+ <update id="update" parameterType="IssueFilter">
+ update issue_filters set
+ name=#{name},
+ user_id=#{userId},
+ shared=#{shared},
+ description=#{description},
+ data=#{data},
+ updated_at=current_timestamp
+ where id=#{id}
+ </update>
+
+ <delete id="delete" parameterType="int">
+ delete from issue_filters where id=#{id}
+ </delete>
+
+</mapper>
diff --git a/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql b/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql
index 9f3acacff47..aaef7a8f832 100644
--- a/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql
+++ b/sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql
@@ -166,6 +166,8 @@ INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('400');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('401');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('402');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('403');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('410');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('411');
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;
diff --git a/sonar-core/src/main/resources/org/sonar/core/persistence/schema-h2.ddl b/sonar-core/src/main/resources/org/sonar/core/persistence/schema-h2.ddl
index 19ce838fa10..2e65ee3b2d5 100644
--- a/sonar-core/src/main/resources/org/sonar/core/persistence/schema-h2.ddl
+++ b/sonar-core/src/main/resources/org/sonar/core/persistence/schema-h2.ddl
@@ -504,6 +504,24 @@ CREATE TABLE "ISSUE_CHANGES" (
"UPDATED_AT" TIMESTAMP,
);
+CREATE TABLE "ISSUE_FILTERS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "NAME" VARCHAR(100) NOT NULL,
+ "SHARED" BOOLEAN NOT NULL DEFAULT FALSE,
+ "USER_ID" INTEGER,
+ "DESCRIPTION" VARCHAR(4000),
+ "DATA" CLOB(2147483647),
+ "CREATED_AT" TIMESTAMP,
+ "UPDATED_AT" TIMESTAMP
+);
+
+CREATE TABLE "ISSUE_FILTER_FAVOURITES" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "USER_ID" INTEGER NOT NULL,
+ "ISSUE_FILTER_ID" INTEGER NOT NULL,
+ "CREATED_AT" TIMESTAMP
+);
+
CREATE TABLE "SNAPSHOT_DATA" (
"ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
"SNAPSHOT_ID" INTEGER,
@@ -638,4 +656,8 @@ CREATE INDEX "ISSUE_CHANGES_KEE" ON "ISSUE_CHANGES" ("KEE");
CREATE INDEX "ISSUE_CHANGES_ISSUE_KEY" ON "ISSUE_CHANGES" ("ISSUE_KEY");
+CREATE INDEX "ISSUE_FILTERS_NAME" ON "ISSUE_FILTERS" ("NAME");
+
+CREATE INDEX "ISSUE_FILTER_FAVS_USERID" ON "ISSUE_FILTER_FAVOURITES" ("USER_ID");
+
CREATE UNIQUE INDEX "USERS_LOGIN" ON "USERS" ("LOGIN");
diff --git a/sonar-core/src/test/java/org/sonar/core/issue/db/IssueFilterDaoTest.java b/sonar-core/src/test/java/org/sonar/core/issue/db/IssueFilterDaoTest.java
new file mode 100644
index 00000000000..8cc8ec08558
--- /dev/null
+++ b/sonar-core/src/test/java/org/sonar/core/issue/db/IssueFilterDaoTest.java
@@ -0,0 +1,103 @@
+/*
+ * 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.issue.db;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.core.persistence.AbstractDaoTestCase;
+
+import java.util.List;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class IssueFilterDaoTest extends AbstractDaoTestCase {
+
+ IssueFilterDao dao;
+
+ @Before
+ public void createDao() {
+ dao = new IssueFilterDao(getMyBatis());
+ }
+
+ @Test
+ public void should_select_by_id() {
+ setupData("shared");
+
+ IssueFilterDto filter = dao.selectById(1);
+
+ assertThat(filter.getId()).isEqualTo(1L);
+ assertThat(filter.getName()).isEqualTo("Sonar Issues");
+ assertThat(filter.isShared()).isTrue();
+
+ assertThat(dao.selectById(123)).isNull();
+ }
+
+ @Test
+ public void should_select_by_user() {
+ setupData("should_select_by_user");
+
+ List<IssueFilterDto> results = dao.selectByUser(2);
+
+ assertThat(results).hasSize(2);
+ }
+
+ @Test
+ public void should_insert() {
+ setupData("shared");
+
+ IssueFilterDto filterDto = new IssueFilterDto();
+ filterDto.setName("Sonar Open issues");
+ filterDto.setUserId(2L);
+ filterDto.setShared(true);
+ filterDto.setDescription("All open issues on Sonar");
+ filterDto.setData("statuses=OPEN|componentRoots=org.codehaus.sonar");
+
+ dao.insert(filterDto);
+
+ checkTables("should_insert", new String[]{"created_at", "updated_at"}, "issue_filters");
+ }
+
+ @Test
+ public void should_update() {
+ setupData("shared");
+
+ IssueFilterDto filterDto = new IssueFilterDto();
+ filterDto.setId(2L);
+ filterDto.setName("Closed issues");
+ filterDto.setUserId(3L);
+ filterDto.setShared(false);
+ filterDto.setDescription("All closed issues");
+ filterDto.setData("statuses=CLOSED");
+
+ dao.update(filterDto);
+
+ checkTables("should_update", new String[]{"created_at", "updated_at"}, "issue_filters");
+ }
+
+ @Test
+ public void should_delete() {
+ setupData("shared");
+
+ dao.delete(1);
+
+ checkTables("should_delete", new String[]{"created_at", "updated_at"}, "issue_filters");
+ }
+}
diff --git a/sonar-core/src/test/java/org/sonar/core/measure/MeasureFilterDaoTest.java b/sonar-core/src/test/java/org/sonar/core/measure/MeasureFilterDaoTest.java
index a62a8c5420e..04e3ffd3098 100644
--- a/sonar-core/src/test/java/org/sonar/core/measure/MeasureFilterDaoTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/measure/MeasureFilterDaoTest.java
@@ -43,7 +43,6 @@ public class MeasureFilterDaoTest extends AbstractDaoTestCase {
assertThat(filter.getName()).isEqualTo("Projects");
}
-
@Test
public void should_not_find_filter() {
setupData("shared");
diff --git a/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueFilterDaoTest/shared.xml b/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueFilterDaoTest/shared.xml
new file mode 100644
index 00000000000..3dd5ac09a05
--- /dev/null
+++ b/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueFilterDaoTest/shared.xml
@@ -0,0 +1,23 @@
+<dataset>
+
+ <issue_filters
+ id="1"
+ name="Sonar Issues"
+ user_id="1"
+ shared="[true]"
+ description="All issues of Sonar"
+ data="componentRoots=org.codehaus.sonar"
+ created_at="2013-06-10"
+ updated_at="2013-06-10" />
+
+ <issue_filters
+ id="2"
+ name="Open issues"
+ user_id="2"
+ shared="[false]"
+ description="All open issues"
+ data="statuses=OPEN"
+ created_at="2013-06-10"
+ updated_at="2013-06-10" />
+
+</dataset>
diff --git a/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueFilterDaoTest/should_delete-result.xml b/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueFilterDaoTest/should_delete-result.xml
new file mode 100644
index 00000000000..b218f0457b2
--- /dev/null
+++ b/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueFilterDaoTest/should_delete-result.xml
@@ -0,0 +1,13 @@
+<dataset>
+
+ <issue_filters
+ id="2"
+ name="Open issues"
+ user_id="2"
+ shared="[false]"
+ description="All open issues"
+ data="statuses=OPEN"
+ created_at="2013-06-10"
+ updated_at="2013-06-10" />
+
+</dataset>
diff --git a/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueFilterDaoTest/should_insert-result.xml b/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueFilterDaoTest/should_insert-result.xml
new file mode 100644
index 00000000000..dc7196eafa8
--- /dev/null
+++ b/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueFilterDaoTest/should_insert-result.xml
@@ -0,0 +1,34 @@
+<dataset>
+
+ <issue_filters
+ id="1"
+ name="Sonar Issues"
+ user_id="1"
+ shared="[true]"
+ description="All issues of Sonar"
+ data="componentRoots=org.codehaus.sonar"
+ created_at="2013-06-10"
+ updated_at="2013-06-10" />
+
+ <issue_filters
+ id="2"
+ name="Open issues"
+ user_id="2"
+ shared="[false]"
+ description="All open issues"
+ data="statuses=OPEN"
+ created_at="2013-06-10"
+ updated_at="2013-06-10" />
+
+
+ <issue_filters
+ id="3"
+ name="Sonar Open issues"
+ user_id="2"
+ shared="[true]"
+ description="All open issues on Sonar"
+ data="statuses=OPEN|componentRoots=org.codehaus.sonar"
+ created_at="2013-06-10"
+ updated_at="2013-06-10" />
+
+</dataset>
diff --git a/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueFilterDaoTest/should_select_by_user.xml b/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueFilterDaoTest/should_select_by_user.xml
new file mode 100644
index 00000000000..fda801cd549
--- /dev/null
+++ b/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueFilterDaoTest/should_select_by_user.xml
@@ -0,0 +1,33 @@
+<dataset>
+
+ <issue_filters
+ id="1"
+ name="Sonar Issues"
+ user_id="1"
+ shared="[true]"
+ description="All issues of Sonar"
+ data="componentRoots=org.codehaus.sonar"
+ created_at="2013-06-10"
+ updated_at="2013-06-10" />
+
+ <issue_filters
+ id="2"
+ name="Open issues"
+ user_id="2"
+ shared="[false]"
+ description="All open issues"
+ data="statuses=OPEN"
+ created_at="2013-06-10"
+ updated_at="2013-06-10" />
+
+ <issue_filters
+ id="3"
+ name="Sonar Open issues"
+ user_id="2"
+ shared="[true]"
+ description="All open issues on Sonar"
+ data="statuses=OPEN|componentRoots=org.codehaus.sonar"
+ created_at="2013-06-10"
+ updated_at="2013-06-10" />
+
+</dataset>
diff --git a/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueFilterDaoTest/should_update-result.xml b/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueFilterDaoTest/should_update-result.xml
new file mode 100644
index 00000000000..4b35add7346
--- /dev/null
+++ b/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueFilterDaoTest/should_update-result.xml
@@ -0,0 +1,23 @@
+<dataset>
+
+ <issue_filters
+ id="1"
+ name="Sonar Issues"
+ user_id="1"
+ shared="[true]"
+ description="All issues of Sonar"
+ data="componentRoots=org.codehaus.sonar"
+ created_at="2013-06-10"
+ updated_at="2013-06-10" />
+
+ <issue_filters
+ id="2"
+ name="Closed issues"
+ user_id="3"
+ shared="[false]"
+ description="All closed issues"
+ data="statuses=CLOSED"
+ created_at="2013-06-10"
+ updated_at="2013-06-11" />
+
+</dataset>
diff --git a/sonar-server/src/main/java/org/sonar/server/issue/IssueFilterService.java b/sonar-server/src/main/java/org/sonar/server/issue/IssueFilterService.java
new file mode 100644
index 00000000000..d4364d26946
--- /dev/null
+++ b/sonar-server/src/main/java/org/sonar/server/issue/IssueFilterService.java
@@ -0,0 +1,33 @@
+/*
+ * 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.server.issue;
+
+import org.sonar.api.ServerComponent;
+import org.sonar.core.issue.db.IssueFilterDao;
+
+public class IssueFilterService implements ServerComponent {
+
+ private IssueFilterDao issueFilterDao;
+
+ public IssueFilterService(IssueFilterDao issueFilterDao) {
+ this.issueFilterDao = issueFilterDao;
+ }
+}
diff --git a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
index 8a52b6f8124..1878f6de95c 100644
--- a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
+++ b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java
@@ -273,6 +273,7 @@ public final class Platform {
servicesContainer.addSingleton(IssueNotifications.class);
servicesContainer.addSingleton(ActionService.class);
servicesContainer.addSingleton(Actions.class);
+ servicesContainer.addSingleton(IssueFilterService.class);
// rules
servicesContainer.addSingleton(RubyRuleService.class);
diff --git a/sonar-server/src/main/webapp/WEB-INF/db/migrate/410_create_issue_filters.rb b/sonar-server/src/main/webapp/WEB-INF/db/migrate/410_create_issue_filters.rb
new file mode 100644
index 00000000000..ff63ed785b4
--- /dev/null
+++ b/sonar-server/src/main/webapp/WEB-INF/db/migrate/410_create_issue_filters.rb
@@ -0,0 +1,38 @@
+#
+# Sonar, entreprise quality control 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.
+#
+#
+# Sonar 3.6
+# See SONAR-4383
+#
+class CreateIssueFilters < ActiveRecord::Migration
+
+ def self.up
+ create_table 'issue_filters' do |t|
+ t.column 'name', :string, :null => false, :limit => 100
+ t.column 'user_id', :integer, :null => true
+ t.column 'shared', :boolean, :default => false, :null => false
+ t.column 'description', :string, :null => true, :limit => 4000
+ t.column 'data', :text, :null => true
+ t.timestamps
+ end
+ add_index 'issue_filters', 'name', :name => 'issue_filters_name'
+ end
+
+end \ No newline at end of file
diff --git a/sonar-server/src/main/webapp/WEB-INF/db/migrate/411_create_issue_filter_favourites.rb b/sonar-server/src/main/webapp/WEB-INF/db/migrate/411_create_issue_filter_favourites.rb
new file mode 100644
index 00000000000..322c19aaa53
--- /dev/null
+++ b/sonar-server/src/main/webapp/WEB-INF/db/migrate/411_create_issue_filter_favourites.rb
@@ -0,0 +1,37 @@
+#
+# Sonar, entreprise quality control 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.
+#
+
+#
+# Sonar 3.6
+# See SONAR-4383
+#
+class CreateIssueFilterFavourites < ActiveRecord::Migration
+
+ def self.up
+ create_table 'issue_filter_favourites' do |t|
+ t.column 'user_id', :integer, :null => false
+ t.column 'issue_filter_id', :integer, :null => false
+ t.column 'created_at', :datetime
+ end
+ add_index 'issue_filter_favourites', 'user_id', :name => 'issue_filter_favs_userid'
+ end
+
+end
+