src/main/java/de/uapcore/lightpit/dao/postgres/PGIssueDao.java

Mon, 01 Jun 2020 14:46:58 +0200

author
Mike Becker <universe@uap-core.de>
date
Mon, 01 Jun 2020 14:46:58 +0200
changeset 86
0a658e53177c
parent 83
24a3596b8f98
child 88
1438e5a22c55
permissions
-rw-r--r--

improves issue overview and adds progress information

     1 /*
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * Copyright 2018 Mike Becker. All rights reserved.
     5  *
     6  * Redistribution and use in source and binary forms, with or without
     7  * modification, are permitted provided that the following conditions are met:
     8  *
     9  *   1. Redistributions of source code must retain the above copyright
    10  *      notice, this list of conditions and the following disclaimer.
    11  *
    12  *   2. Redistributions in binary form must reproduce the above copyright
    13  *      notice, this list of conditions and the following disclaimer in the
    14  *      documentation and/or other materials provided with the distribution.
    15  *
    16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    26  * POSSIBILITY OF SUCH DAMAGE.
    27  *
    28  */
    29 package de.uapcore.lightpit.dao.postgres;
    31 import de.uapcore.lightpit.dao.IssueDao;
    32 import de.uapcore.lightpit.entities.*;
    34 import java.sql.Connection;
    35 import java.sql.PreparedStatement;
    36 import java.sql.ResultSet;
    37 import java.sql.SQLException;
    38 import java.util.ArrayList;
    39 import java.util.List;
    40 import java.util.Objects;
    42 import static de.uapcore.lightpit.dao.Functions.*;
    44 public final class PGIssueDao implements IssueDao {
    46     private final PreparedStatement insert, update, list, listForVersion, find;
    47     private final PreparedStatement affectedVersions, scheduledVersions, resolvedVersions;
    48     private final PreparedStatement clearAffected, clearScheduled, clearResolved;
    49     private final PreparedStatement insertAffected, insertScheduled, insertResolved;
    51     public PGIssueDao(Connection connection) throws SQLException {
    52         list = connection.prepareStatement(
    53                 "select issueid, project, p.name as projectname, status, category, subject, i.description, " +
    54                         "userid, username, givenname, lastname, mail, " +
    55                         "created, updated, eta " +
    56                         "from lpit_issue i " +
    57                         "left join lpit_project p on project = projectid " +
    58                         "left join lpit_user on userid = assignee " +
    59                         "where project = ? "+
    60                         "order by eta asc, updated desc");
    62         listForVersion = connection.prepareStatement(
    63                 "with issue_version as ( "+
    64                         "select issueid, versionid from lpit_issue_affected_version union "+
    65                         "select issueid, versionid from lpit_issue_scheduled_version union "+
    66                         "select issueid, versionid from lpit_issue_resolved_version) "+
    67                         "select issueid, project, p.name as projectname, status, category, subject, i.description, " +
    68                         "userid, username, givenname, lastname, mail, " +
    69                         "created, updated, eta " +
    70                         "from lpit_issue i " +
    71                         "join issue_version using (issueid) "+
    72                         "left join lpit_project p on project = projectid " +
    73                         "left join lpit_user on userid = assignee " +
    74                         "where versionid = ? "+
    75                         "order by eta asc, updated desc"
    76         );
    78         find = connection.prepareStatement(
    79                 "select issueid, project, p.name as projectname, status, category, subject, i.description, " +
    80                         "userid, username, givenname, lastname, mail, " +
    81                         "created, updated, eta " +
    82                         "from lpit_issue i " +
    83                         "left join lpit_project p on project = projectid " +
    84                         "left join lpit_user on userid = assignee " +
    85                         "where issueid = ? ");
    87         insert = connection.prepareStatement(
    88                 "insert into lpit_issue (project, status, category, subject, description, assignee, eta) " +
    89                         "values (?, ?::issue_status, ?::issue_category, ?, ?, ?, ?) returning issueid"
    90         );
    91         update = connection.prepareStatement(
    92                 "update lpit_issue set updated = now(), status = ?::issue_status, category = ?::issue_category, " +
    93                         "subject = ?, description = ?, assignee = ?, eta = ? where issueid = ?"
    94         );
    96         affectedVersions = connection.prepareStatement(
    97                 "select versionid, name, status, ordinal " +
    98                         "from lpit_version join lpit_issue_affected_version using (versionid) " +
    99                         "where issueid = ? " +
   100                         "order by ordinal, name"
   101         );
   102         clearAffected = connection.prepareStatement("delete from lpit_issue_affected_version where issueid = ?");
   103         insertAffected = connection.prepareStatement("insert into lpit_issue_affected_version (issueid, versionid) values (?,?)");
   105         scheduledVersions = connection.prepareStatement(
   106                 "select versionid, name, status, ordinal " +
   107                         "from lpit_version join lpit_issue_scheduled_version using (versionid) " +
   108                         "where issueid = ? " +
   109                         "order by ordinal, name"
   110         );
   111         clearScheduled = connection.prepareStatement("delete from lpit_issue_scheduled_version where issueid = ?");
   112         insertScheduled = connection.prepareStatement("insert into lpit_issue_scheduled_version (issueid, versionid) values (?,?)");
   114         resolvedVersions = connection.prepareStatement(
   115                 "select versionid, name, status, ordinal " +
   116                         "from lpit_version v join lpit_issue_resolved_version using (versionid) " +
   117                         "where issueid = ? " +
   118                         "order by ordinal, name"
   119         );
   120         clearResolved = connection.prepareStatement("delete from lpit_issue_resolved_version where issueid = ?");
   121         insertResolved = connection.prepareStatement("insert into lpit_issue_resolved_version (issueid, versionid) values (?,?)");
   122     }
   124     private User obtainAssignee(ResultSet result) throws SQLException {
   125         final int id = result.getInt("userid");
   126         if (id != 0) {
   127             final var user = new User(id);
   128             user.setUsername(result.getString("username"));
   129             user.setGivenname(result.getString("givenname"));
   130             user.setLastname(result.getString("lastname"));
   131             user.setMail(result.getString("mail"));
   132             return user;
   133         } else {
   134             return null;
   135         }
   136     }
   138     private Issue mapColumns(ResultSet result) throws SQLException {
   139         final var project = new Project(result.getInt("project"));
   140         project.setName(result.getString("projectname"));
   141         final var issue = new Issue(result.getInt("issueid"));
   142         issue.setProject(project);
   143         issue.setStatus(IssueStatus.valueOf(result.getString("status")));
   144         issue.setCategory(IssueCategory.valueOf(result.getString("category")));
   145         issue.setSubject(result.getString("subject"));
   146         issue.setDescription(result.getString("description"));
   147         issue.setAssignee(obtainAssignee(result));
   148         issue.setCreated(result.getTimestamp("created"));
   149         issue.setUpdated(result.getTimestamp("updated"));
   150         issue.setEta(result.getDate("eta"));
   151         return issue;
   152     }
   154     private Version mapVersion(ResultSet result) throws SQLException {
   155         final var version = new Version(result.getInt("versionid"));
   156         version.setName(result.getString("name"));
   157         version.setOrdinal(result.getInt("ordinal"));
   158         version.setStatus(VersionStatus.valueOf(result.getString("status")));
   159         return version;
   160     }
   162     private void updateVersionLists(Issue instance) throws SQLException {
   163         clearAffected.setInt(1, instance.getId());
   164         clearScheduled.setInt(1, instance.getId());
   165         clearResolved.setInt(1, instance.getId());
   166         insertAffected.setInt(1, instance.getId());
   167         insertScheduled.setInt(1, instance.getId());
   168         insertResolved.setInt(1, instance.getId());
   169         clearAffected.executeUpdate();
   170         clearScheduled.executeUpdate();
   171         clearResolved.executeUpdate();
   172         for (Version v : instance.getAffectedVersions()) {
   173             insertAffected.setInt(2, v.getId());
   174             insertAffected.executeUpdate();
   175         }
   176         for (Version v : instance.getScheduledVersions()) {
   177             insertScheduled.setInt(2, v.getId());
   178             insertScheduled.executeUpdate();
   179         }
   180         for (Version v : instance.getResolvedVersions()) {
   181             insertResolved.setInt(2, v.getId());
   182             insertResolved.executeUpdate();
   183         }
   184     }
   186     @Override
   187     public void save(Issue instance) throws SQLException {
   188         Objects.requireNonNull(instance.getSubject());
   189         Objects.requireNonNull(instance.getProject());
   190         insert.setInt(1, instance.getProject().getId());
   191         insert.setString(2, instance.getStatus().name());
   192         insert.setString(3, instance.getCategory().name());
   193         insert.setString(4, instance.getSubject());
   194         setStringOrNull(insert, 5, instance.getDescription());
   195         setForeignKeyOrNull(insert, 6, instance.getAssignee(), User::getId);
   196         setDateOrNull(insert, 7, instance.getEta());
   197         // insert and retrieve the ID
   198         final var rs = insert.executeQuery();
   199         rs.next();
   200         instance.setId(rs.getInt(1));
   201         updateVersionLists(instance);
   202     }
   204     @Override
   205     public boolean update(Issue instance) throws SQLException {
   206         if (instance.getId() < 0) return false;
   207         Objects.requireNonNull(instance.getSubject());
   208         update.setString(1, instance.getStatus().name());
   209         update.setString(2, instance.getCategory().name());
   210         update.setString(3, instance.getSubject());
   211         setStringOrNull(update, 4, instance.getDescription());
   212         setForeignKeyOrNull(update, 5, instance.getAssignee(), User::getId);
   213         setDateOrNull(update, 6, instance.getEta());
   214         update.setInt(7, instance.getId());
   215         boolean success = update.executeUpdate() > 0;
   216         if (success) {
   217             updateVersionLists(instance);
   218             return true;
   219         } else {
   220             return false;
   221         }
   222     }
   224     private List<Issue> list(PreparedStatement query, int arg) throws SQLException {
   225         query.setInt(1, arg);
   226         List<Issue> issues = new ArrayList<>();
   227         try (var result = query.executeQuery()) {
   228             while (result.next()) {
   229                 issues.add(mapColumns(result));
   230             }
   231         }
   232         return issues;
   233     }
   235     @Override
   236     public List<Issue> list(Project project) throws SQLException {
   237         return list(list, project.getId());
   238     }
   240     @Override
   241     public List<Issue> list(Version version) throws SQLException {
   242         return list(listForVersion, version.getId());
   243     }
   245     @Override
   246     public Issue find(int id) throws SQLException {
   247         find.setInt(1, id);
   248         try (var result = find.executeQuery()) {
   249             if (result.next()) {
   250                 return mapColumns(result);
   251             } else {
   252                 return null;
   253             }
   254         }
   255     }
   257     private List<Version> listVersions(PreparedStatement stmt, Issue issue) throws SQLException {
   258         stmt.setInt(1, issue.getId());
   259         List<Version> versions = new ArrayList<>();
   260         try (var result = stmt.executeQuery()) {
   261             while (result.next()) {
   262                 versions.add(mapVersion(result));
   263             }
   264         }
   265         return versions;
   266     }
   268     @Override
   269     public void joinVersionInformation(Issue issue) throws SQLException {
   270         Objects.requireNonNull(issue.getProject());
   271         issue.setAffectedVersions(listVersions(affectedVersions, issue));
   272         issue.setScheduledVersions(listVersions(scheduledVersions, issue));
   273         issue.setResolvedVersions(listVersions(resolvedVersions, issue));
   274     }
   275 }

mercurial