Thu, 19 Nov 2020 13:58:54 +0100
migrates DAO classes
1.1 --- a/src/main/java/de/uapcore/lightpit/AbstractLightPITServlet.java Fri Nov 06 10:50:32 2020 +0100 1.2 +++ b/src/main/java/de/uapcore/lightpit/AbstractLightPITServlet.java Thu Nov 19 13:58:54 2020 +0100 1.3 @@ -28,8 +28,8 @@ 1.4 */ 1.5 package de.uapcore.lightpit; 1.6 1.7 -import de.uapcore.lightpit.dao.DataAccessObjects; 1.8 -import de.uapcore.lightpit.dao.postgres.PGDataAccessObjects; 1.9 +import de.uapcore.lightpit.dao.DaoProvider; 1.10 +import de.uapcore.lightpit.dao.postgres.PGDaoProvider; 1.11 import org.slf4j.Logger; 1.12 import org.slf4j.LoggerFactory; 1.13 1.14 @@ -100,15 +100,15 @@ 1.15 * @param connection the SQL connection 1.16 * @return a set of data access objects 1.17 */ 1.18 - private DataAccessObjects createDataAccessObjects(Connection connection) throws SQLException { 1.19 + private DaoProvider createDataAccessObjects(Connection connection) throws SQLException { 1.20 final var df = (DataSourceProvider) getServletContext().getAttribute(DataSourceProvider.Companion.getSC_ATTR_NAME()); 1.21 if (df.getDialect() == DataSourceProvider.Dialect.Postgres) { 1.22 - return new PGDataAccessObjects(connection); 1.23 + return new PGDaoProvider(connection); 1.24 } 1.25 throw new UnsupportedOperationException("Non-exhaustive if-else - this is a bug."); 1.26 } 1.27 1.28 - private void invokeMapping(Map.Entry<PathPattern, Method> mapping, HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws IOException { 1.29 + private void invokeMapping(Map.Entry<PathPattern, Method> mapping, HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws IOException { 1.30 final var pathPattern = mapping.getKey(); 1.31 final var method = mapping.getValue(); 1.32 try { 1.33 @@ -121,7 +121,7 @@ 1.34 } else if (paramTypes[i].isAssignableFrom(HttpServletResponse.class)) { 1.35 paramValues[i] = resp; 1.36 } 1.37 - if (paramTypes[i].isAssignableFrom(DataAccessObjects.class)) { 1.38 + if (paramTypes[i].isAssignableFrom(DaoProvider.class)) { 1.39 paramValues[i] = dao; 1.40 } 1.41 if (paramTypes[i].isAssignableFrom(PathParameters.class)) { 1.42 @@ -180,7 +180,7 @@ 1.43 paramsInjectible &= HttpServletRequest.class.isAssignableFrom(param) 1.44 || HttpServletResponse.class.isAssignableFrom(param) 1.45 || PathParameters.class.isAssignableFrom(param) 1.46 - || DataAccessObjects.class.isAssignableFrom(param); 1.47 + || DaoProvider.class.isAssignableFrom(param); 1.48 } 1.49 if (paramsInjectible) { 1.50 try {
2.1 --- a/src/main/java/de/uapcore/lightpit/dao/ChildEntityDao.java Fri Nov 06 10:50:32 2020 +0100 2.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 2.3 @@ -1,116 +0,0 @@ 2.4 -/* 2.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 2.6 - * 2.7 - * Copyright 2018 Mike Becker. All rights reserved. 2.8 - * 2.9 - * Redistribution and use in source and binary forms, with or without 2.10 - * modification, are permitted provided that the following conditions are met: 2.11 - * 2.12 - * 1. Redistributions of source code must retain the above copyright 2.13 - * notice, this list of conditions and the following disclaimer. 2.14 - * 2.15 - * 2. Redistributions in binary form must reproduce the above copyright 2.16 - * notice, this list of conditions and the following disclaimer in the 2.17 - * documentation and/or other materials provided with the distribution. 2.18 - * 2.19 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2.20 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2.21 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2.22 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 2.23 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2.24 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2.25 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2.26 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2.27 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2.28 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2.29 - * POSSIBILITY OF SUCH DAMAGE. 2.30 - * 2.31 - */ 2.32 -package de.uapcore.lightpit.dao; 2.33 - 2.34 -import java.sql.SQLException; 2.35 -import java.util.List; 2.36 - 2.37 -public interface ChildEntityDao<T, P> { 2.38 - 2.39 - /** 2.40 - * Lists all entities being a child of the specified parent. 2.41 - * @param parent the parent 2.42 - * @return the list of child instances 2.43 - * @throws SQLException on any kind of SQL errors 2.44 - */ 2.45 - List<T> list(P parent) throws SQLException; 2.46 - 2.47 - /** 2.48 - * Finds an entity by its integer ID. 2.49 - * It is not guaranteed that referenced entities are automatically joined. 2.50 - * 2.51 - * @param id the id 2.52 - * @return the enity or null if there is no such entity 2.53 - * @throws SQLException on any kind of SQL errors 2.54 - */ 2.55 - T find(int id) throws SQLException; 2.56 - 2.57 - /** 2.58 - * Inserts an instance into database. 2.59 - * It is not guaranteed that generated fields will be updated in the instance. 2.60 - * 2.61 - * @param instance the instance to insert 2.62 - * @param parent a reference to the parent 2.63 - * @throws SQLException on any kind of SQL errors 2.64 - */ 2.65 - void save(T instance, P parent) throws SQLException; 2.66 - 2.67 - /** 2.68 - * Updates an instance in the database. 2.69 - * 2.70 - * @param instance the instance to insert 2.71 - * @return true if an instance has been updated, false if no instance with the specified ID was found 2.72 - * @throws SQLException on any kind of SQL errors 2.73 - */ 2.74 - boolean update(T instance) throws SQLException; 2.75 - 2.76 - /** 2.77 - * Updates an instance in the database changing the parent. 2.78 - * This operation is not supported by default. 2.79 - * 2.80 - * @param instance the instance to insert 2.81 - * @param newParent a reference to the new parent 2.82 - * @return true if an instance has been updated, false if no instance with the specified ID was found 2.83 - * @throws SQLException on any kind of SQL errors 2.84 - * @see #isChangingParentSupported() 2.85 - */ 2.86 - default boolean update(T instance, P newParent) throws SQLException { 2.87 - throw new UnsupportedOperationException(); 2.88 - } 2.89 - 2.90 - /** 2.91 - * Returns true if changing the parent is supported by this DAO. 2.92 - * This method must return true, if {@link #update(Object, Object)} is implemented. 2.93 - * @return true, if changing the parent is supported 2.94 - */ 2.95 - default boolean isChangingParentSupported() { 2.96 - return false; 2.97 - } 2.98 - 2.99 - /** 2.100 - * Inserts or updates an instance in the database. 2.101 - * Tries an update first and if that fails, performs a save. 2.102 - * If changing a parent is not supported by this DAO, 2.103 - * specifying an alternate parent for an existing instance has no effect. 2.104 - * 2.105 - * @param instance the instance to insert or update 2.106 - * @param parent a reference to the parent 2.107 - * @throws SQLException on any kind of SQL errors 2.108 - * @see #update(Object) 2.109 - * @see #update(Object, Object) 2.110 - * @see #save(Object, Object) 2.111 - */ 2.112 - default void saveOrUpdate(T instance, P parent) throws SQLException { 2.113 - if (isChangingParentSupported()) { 2.114 - if (!update(instance, parent)) save(instance, parent); 2.115 - } else { 2.116 - if (!update(instance)) save(instance, parent); 2.117 - } 2.118 - } 2.119 -}
3.1 --- a/src/main/java/de/uapcore/lightpit/dao/ComponentDao.java Fri Nov 06 10:50:32 2020 +0100 3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 3.3 @@ -1,38 +0,0 @@ 3.4 -/* 3.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3.6 - * 3.7 - * Copyright 2018 Mike Becker. All rights reserved. 3.8 - * 3.9 - * Redistribution and use in source and binary forms, with or without 3.10 - * modification, are permitted provided that the following conditions are met: 3.11 - * 3.12 - * 1. Redistributions of source code must retain the above copyright 3.13 - * notice, this list of conditions and the following disclaimer. 3.14 - * 3.15 - * 2. Redistributions in binary form must reproduce the above copyright 3.16 - * notice, this list of conditions and the following disclaimer in the 3.17 - * documentation and/or other materials provided with the distribution. 3.18 - * 3.19 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 3.20 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 3.21 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 3.22 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 3.23 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 3.24 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 3.25 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 3.26 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 3.27 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3.28 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3.29 - * POSSIBILITY OF SUCH DAMAGE. 3.30 - * 3.31 - */ 3.32 -package de.uapcore.lightpit.dao; 3.33 - 3.34 -import de.uapcore.lightpit.entities.Component; 3.35 -import de.uapcore.lightpit.entities.Project; 3.36 - 3.37 -import java.sql.SQLException; 3.38 - 3.39 -public interface ComponentDao extends ChildEntityDao<Component, Project> { 3.40 - Component findByNode(Project parent, String node) throws SQLException; 3.41 -}
4.1 --- a/src/main/java/de/uapcore/lightpit/dao/DataAccessObjects.java Fri Nov 06 10:50:32 2020 +0100 4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 4.3 @@ -1,41 +0,0 @@ 4.4 -/* 4.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 4.6 - * 4.7 - * Copyright 2018 Mike Becker. All rights reserved. 4.8 - * 4.9 - * Redistribution and use in source and binary forms, with or without 4.10 - * modification, are permitted provided that the following conditions are met: 4.11 - * 4.12 - * 1. Redistributions of source code must retain the above copyright 4.13 - * notice, this list of conditions and the following disclaimer. 4.14 - * 4.15 - * 2. Redistributions in binary form must reproduce the above copyright 4.16 - * notice, this list of conditions and the following disclaimer in the 4.17 - * documentation and/or other materials provided with the distribution. 4.18 - * 4.19 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 4.20 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4.21 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4.22 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 4.23 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 4.24 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 4.25 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 4.26 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 4.27 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 4.28 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4.29 - * POSSIBILITY OF SUCH DAMAGE. 4.30 - * 4.31 - */ 4.32 -package de.uapcore.lightpit.dao; 4.33 - 4.34 -public interface DataAccessObjects { 4.35 - UserDao getUserDao(); 4.36 - 4.37 - ProjectDao getProjectDao(); 4.38 - 4.39 - VersionDao getVersionDao(); 4.40 - 4.41 - ComponentDao getComponentDao(); 4.42 - 4.43 - IssueDao getIssueDao(); 4.44 -}
5.1 --- a/src/main/java/de/uapcore/lightpit/dao/IssueDao.java Fri Nov 06 10:50:32 2020 +0100 5.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 5.3 @@ -1,111 +0,0 @@ 5.4 -/* 5.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 5.6 - * 5.7 - * Copyright 2018 Mike Becker. All rights reserved. 5.8 - * 5.9 - * Redistribution and use in source and binary forms, with or without 5.10 - * modification, are permitted provided that the following conditions are met: 5.11 - * 5.12 - * 1. Redistributions of source code must retain the above copyright 5.13 - * notice, this list of conditions and the following disclaimer. 5.14 - * 5.15 - * 2. Redistributions in binary form must reproduce the above copyright 5.16 - * notice, this list of conditions and the following disclaimer in the 5.17 - * documentation and/or other materials provided with the distribution. 5.18 - * 5.19 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 5.20 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 5.21 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 5.22 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 5.23 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 5.24 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 5.25 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 5.26 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 5.27 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 5.28 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 5.29 - * POSSIBILITY OF SUCH DAMAGE. 5.30 - * 5.31 - */ 5.32 -package de.uapcore.lightpit.dao; 5.33 - 5.34 -import de.uapcore.lightpit.entities.*; 5.35 - 5.36 -import java.sql.SQLException; 5.37 -import java.util.List; 5.38 - 5.39 -public interface IssueDao extends ChildEntityDao<Issue, Project> { 5.40 - 5.41 - /** 5.42 - * Lists all issues that are related to the specified component and version. 5.43 - * If component or version is null, search for issues that are not assigned to any 5.44 - * component or version, respectively. 5.45 - * 5.46 - * @param project the project 5.47 - * @param component the component or null 5.48 - * @param version the version or null 5.49 - * @return a list of issues 5.50 - * @throws SQLException on any kind of SQL error 5.51 - */ 5.52 - List<Issue> list(Project project, Component component, Version version) throws SQLException; 5.53 - 5.54 - /** 5.55 - * Lists all issues that are related to the specified version. 5.56 - * If the version is null, lists issues that are not assigned to any version. 5.57 - * 5.58 - * @param project the project (mandatory) 5.59 - * @param version the version or null 5.60 - * @return a list of issues 5.61 - * @throws SQLException on any kind of SQL error 5.62 - */ 5.63 - List<Issue> list(Project project, Version version) throws SQLException; 5.64 - 5.65 - /** 5.66 - * Lists all issues that are related to the specified component. 5.67 - * If the component is null, lists issues that are not assigned to a component. 5.68 - * 5.69 - * @param project the project (mandatory) 5.70 - * @param component the component or null 5.71 - * @return a list of issues 5.72 - * @throws SQLException on any kind of SQL error 5.73 - */ 5.74 - List<Issue> list(Project project, Component component) throws SQLException; 5.75 - 5.76 - /** 5.77 - * Lists all comments for a specific issue in chronological order. 5.78 - * 5.79 - * @param issue the issue 5.80 - * @return the list of comments 5.81 - * @throws SQLException on any kind of SQL error 5.82 - */ 5.83 - List<IssueComment> listComments(Issue issue) throws SQLException; 5.84 - 5.85 - /** 5.86 - * Stores the specified comment in database. 5.87 - * This is an update-or-insert operation. 5.88 - * 5.89 - * @param issue the issue to save the comment for 5.90 - * @param comment the comment to save 5.91 - * @throws SQLException on any kind of SQL error 5.92 - */ 5.93 - void saveComment(Issue issue, IssueComment comment) throws SQLException; 5.94 - 5.95 - /** 5.96 - * Saves an instances to the database. 5.97 - * Implementations of this DAO must guarantee that the generated ID is stored in the instance. 5.98 - * 5.99 - * @param instance the instance to insert 5.100 - * @param project the parent project 5.101 - * @throws SQLException on any kind of SQL error 5.102 - * @see Issue#setId(int) 5.103 - */ 5.104 - @Override 5.105 - void save(Issue instance, Project project) throws SQLException; 5.106 - 5.107 - /** 5.108 - * Retrieves the affected, scheduled and resolved versions for the specified issue. 5.109 - * 5.110 - * @param issue the issue to join the information for 5.111 - * @throws SQLException on any kind of SQL error 5.112 - */ 5.113 - void joinVersionInformation(Issue issue) throws SQLException; 5.114 -}
6.1 --- a/src/main/java/de/uapcore/lightpit/dao/ProjectDao.java Fri Nov 06 10:50:32 2020 +0100 6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 6.3 @@ -1,40 +0,0 @@ 6.4 -/* 6.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 6.6 - * 6.7 - * Copyright 2018 Mike Becker. All rights reserved. 6.8 - * 6.9 - * Redistribution and use in source and binary forms, with or without 6.10 - * modification, are permitted provided that the following conditions are met: 6.11 - * 6.12 - * 1. Redistributions of source code must retain the above copyright 6.13 - * notice, this list of conditions and the following disclaimer. 6.14 - * 6.15 - * 2. Redistributions in binary form must reproduce the above copyright 6.16 - * notice, this list of conditions and the following disclaimer in the 6.17 - * documentation and/or other materials provided with the distribution. 6.18 - * 6.19 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 6.20 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 6.21 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 6.22 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 6.23 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 6.24 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 6.25 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 6.26 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 6.27 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 6.28 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 6.29 - * POSSIBILITY OF SUCH DAMAGE. 6.30 - * 6.31 - */ 6.32 -package de.uapcore.lightpit.dao; 6.33 - 6.34 -import de.uapcore.lightpit.entities.IssueSummary; 6.35 -import de.uapcore.lightpit.entities.Project; 6.36 - 6.37 -import java.sql.SQLException; 6.38 - 6.39 -public interface ProjectDao extends RootEntityDao<Project> { 6.40 - IssueSummary getIssueSummary(Project project) throws SQLException; 6.41 - 6.42 - Project findByNode(String node) throws SQLException; 6.43 -}
7.1 --- a/src/main/java/de/uapcore/lightpit/dao/RootEntityDao.java Fri Nov 06 10:50:32 2020 +0100 7.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 7.3 @@ -1,83 +0,0 @@ 7.4 -/* 7.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 7.6 - * 7.7 - * Copyright 2018 Mike Becker. All rights reserved. 7.8 - * 7.9 - * Redistribution and use in source and binary forms, with or without 7.10 - * modification, are permitted provided that the following conditions are met: 7.11 - * 7.12 - * 1. Redistributions of source code must retain the above copyright 7.13 - * notice, this list of conditions and the following disclaimer. 7.14 - * 7.15 - * 2. Redistributions in binary form must reproduce the above copyright 7.16 - * notice, this list of conditions and the following disclaimer in the 7.17 - * documentation and/or other materials provided with the distribution. 7.18 - * 7.19 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 7.20 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 7.21 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 7.22 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 7.23 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 7.24 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 7.25 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 7.26 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 7.27 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 7.28 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 7.29 - * POSSIBILITY OF SUCH DAMAGE. 7.30 - * 7.31 - */ 7.32 -package de.uapcore.lightpit.dao; 7.33 - 7.34 -import java.sql.SQLException; 7.35 -import java.util.List; 7.36 - 7.37 -public interface RootEntityDao<T> { 7.38 - 7.39 - /** 7.40 - * Lists all entities. 7.41 - * @return a list of all entities 7.42 - * @throws SQLException on any kind of SQL errors 7.43 - */ 7.44 - List<T> list() throws SQLException; 7.45 - 7.46 - /** 7.47 - * Finds an entity by its integer ID. 7.48 - * It is not guaranteed that referenced entities are automatically joined. 7.49 - * 7.50 - * @param id the id 7.51 - * @return the enity or null if there is no such entity 7.52 - * @throws SQLException on any kind of SQL errors 7.53 - */ 7.54 - T find(int id) throws SQLException; 7.55 - 7.56 - /** 7.57 - * Inserts an instance into database. 7.58 - * It is not guaranteed that generated fields will be updated in the instance. 7.59 - * 7.60 - * @param instance the instance to insert 7.61 - * @throws SQLException on any kind of SQL errors 7.62 - */ 7.63 - void save(T instance) throws SQLException; 7.64 - 7.65 - /** 7.66 - * Updates an instance in the database. 7.67 - * 7.68 - * @param instance the instance to insert 7.69 - * @return true if an instance has been updated, false if no instance with the specified ID was found 7.70 - * @throws SQLException on any kind of SQL errors 7.71 - */ 7.72 - boolean update(T instance) throws SQLException; 7.73 - 7.74 - /** 7.75 - * Inserts or updates an instance in the database. 7.76 - * Tries an update first and if that fails, performs a save. 7.77 - * 7.78 - * @param instance the instance to insert or update 7.79 - * @throws SQLException on any kind of SQL errors 7.80 - * @see #update(Object) 7.81 - * @see #save(Object) 7.82 - */ 7.83 - default void saveOrUpdate(T instance) throws SQLException { 7.84 - if (!update(instance)) save(instance); 7.85 - } 7.86 -}
8.1 --- a/src/main/java/de/uapcore/lightpit/dao/UserDao.java Fri Nov 06 10:50:32 2020 +0100 8.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 8.3 @@ -1,47 +0,0 @@ 8.4 -/* 8.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 8.6 - * 8.7 - * Copyright 2018 Mike Becker. All rights reserved. 8.8 - * 8.9 - * Redistribution and use in source and binary forms, with or without 8.10 - * modification, are permitted provided that the following conditions are met: 8.11 - * 8.12 - * 1. Redistributions of source code must retain the above copyright 8.13 - * notice, this list of conditions and the following disclaimer. 8.14 - * 8.15 - * 2. Redistributions in binary form must reproduce the above copyright 8.16 - * notice, this list of conditions and the following disclaimer in the 8.17 - * documentation and/or other materials provided with the distribution. 8.18 - * 8.19 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 8.20 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 8.21 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 8.22 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 8.23 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 8.24 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 8.25 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 8.26 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 8.27 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 8.28 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 8.29 - * POSSIBILITY OF SUCH DAMAGE. 8.30 - * 8.31 - */ 8.32 -package de.uapcore.lightpit.dao; 8.33 - 8.34 -import de.uapcore.lightpit.entities.User; 8.35 - 8.36 -import java.sql.SQLException; 8.37 -import java.util.Optional; 8.38 - 8.39 -public interface UserDao extends RootEntityDao<User> { 8.40 - 8.41 - /** 8.42 - * Tries to find a user by their username. 8.43 - * The search is case-insensitive. 8.44 - * 8.45 - * @param username the username 8.46 - * @return the user object or an empty optional if no such user exists 8.47 - * @throws SQLException 8.48 - */ 8.49 - Optional<User> findByUsername(String username) throws SQLException; 8.50 -}
9.1 --- a/src/main/java/de/uapcore/lightpit/dao/VersionDao.java Fri Nov 06 10:50:32 2020 +0100 9.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 9.3 @@ -1,38 +0,0 @@ 9.4 -/* 9.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 9.6 - * 9.7 - * Copyright 2018 Mike Becker. All rights reserved. 9.8 - * 9.9 - * Redistribution and use in source and binary forms, with or without 9.10 - * modification, are permitted provided that the following conditions are met: 9.11 - * 9.12 - * 1. Redistributions of source code must retain the above copyright 9.13 - * notice, this list of conditions and the following disclaimer. 9.14 - * 9.15 - * 2. Redistributions in binary form must reproduce the above copyright 9.16 - * notice, this list of conditions and the following disclaimer in the 9.17 - * documentation and/or other materials provided with the distribution. 9.18 - * 9.19 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 9.20 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 9.21 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 9.22 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 9.23 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 9.24 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 9.25 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 9.26 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 9.27 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 9.28 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 9.29 - * POSSIBILITY OF SUCH DAMAGE. 9.30 - * 9.31 - */ 9.32 -package de.uapcore.lightpit.dao; 9.33 - 9.34 -import de.uapcore.lightpit.entities.Project; 9.35 -import de.uapcore.lightpit.entities.Version; 9.36 - 9.37 -import java.sql.SQLException; 9.38 - 9.39 -public interface VersionDao extends ChildEntityDao<Version, Project> { 9.40 - Version findByNode(Project parent, String node) throws SQLException; 9.41 -}
10.1 --- a/src/main/java/de/uapcore/lightpit/dao/postgres/PGComponentDao.java Fri Nov 06 10:50:32 2020 +0100 10.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 10.3 @@ -1,130 +0,0 @@ 10.4 -/* 10.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 10.6 - * 10.7 - * Copyright 2018 Mike Becker. All rights reserved. 10.8 - * 10.9 - * Redistribution and use in source and binary forms, with or without 10.10 - * modification, are permitted provided that the following conditions are met: 10.11 - * 10.12 - * 1. Redistributions of source code must retain the above copyright 10.13 - * notice, this list of conditions and the following disclaimer. 10.14 - * 10.15 - * 2. Redistributions in binary form must reproduce the above copyright 10.16 - * notice, this list of conditions and the following disclaimer in the 10.17 - * documentation and/or other materials provided with the distribution. 10.18 - * 10.19 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 10.20 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 10.21 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 10.22 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 10.23 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 10.24 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 10.25 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 10.26 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 10.27 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 10.28 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 10.29 - * POSSIBILITY OF SUCH DAMAGE. 10.30 - * 10.31 - */ 10.32 -package de.uapcore.lightpit.dao.postgres; 10.33 - 10.34 -import de.uapcore.lightpit.dao.ComponentDao; 10.35 -import de.uapcore.lightpit.dao.Functions; 10.36 -import de.uapcore.lightpit.entities.Component; 10.37 -import de.uapcore.lightpit.entities.Project; 10.38 -import de.uapcore.lightpit.entities.User; 10.39 -import de.uapcore.lightpit.types.WebColor; 10.40 - 10.41 -import java.sql.Connection; 10.42 -import java.sql.PreparedStatement; 10.43 -import java.sql.ResultSet; 10.44 -import java.sql.SQLException; 10.45 -import java.util.List; 10.46 - 10.47 -public final class PGComponentDao implements ComponentDao { 10.48 - 10.49 - private final PreparedStatement insert, update, list, find, findByNode; 10.50 - 10.51 - public PGComponentDao(Connection connection) throws SQLException { 10.52 - final var query = "select id, name, node, color, ordinal, description, " + 10.53 - "userid, username, givenname, lastname, mail " + 10.54 - "from lpit_component " + 10.55 - "left join lpit_user on lead = userid"; 10.56 - 10.57 - list = connection.prepareStatement(query + " where project = ? order by ordinal, lower(name)"); 10.58 - 10.59 - find = connection.prepareStatement(query + " where id = ? "); 10.60 - 10.61 - findByNode = connection.prepareStatement(query + " where project = ? and node = ?"); 10.62 - 10.63 - insert = connection.prepareStatement( 10.64 - "insert into lpit_component (name, node, color, ordinal, description, lead, project) values (?, ?, ?, ?, ?, ?, ?)" 10.65 - ); 10.66 - 10.67 - update = connection.prepareStatement( 10.68 - "update lpit_component set name = ?, node = ?, color = ?, ordinal = ?, description = ?, lead = ? where id = ?" 10.69 - ); 10.70 - } 10.71 - 10.72 - private static Component mapColumns(ResultSet result) throws SQLException { 10.73 - final var component = new Component(result.getInt("id")); 10.74 - component.setName(result.getString("name")); 10.75 - component.setNode(result.getString("node")); 10.76 - try { 10.77 - component.setColor(new WebColor(result.getString("color"))); 10.78 - } catch (IllegalArgumentException ex) { 10.79 - // if someone tempered with the database we default the color to black 10.80 - component.setColor(new WebColor("000000")); 10.81 - } 10.82 - component.setOrdinal(result.getInt("ordinal")); 10.83 - component.setDescription(result.getString("description")); 10.84 - component.setLead(PGUserDao.mapColumns(result)); 10.85 - return component; 10.86 - } 10.87 - 10.88 - private static int setColumns(PreparedStatement stmt, Component instance) throws SQLException { 10.89 - int column = 0; 10.90 - stmt.setString(++column, instance.getName()); 10.91 - stmt.setString(++column, instance.getNode()); 10.92 - stmt.setString(++column, instance.getColor().getHex()); 10.93 - stmt.setInt(++column, instance.getOrdinal()); 10.94 - Functions.setStringOrNull(stmt, ++column, instance.getDescription()); 10.95 - Functions.setForeignKeyOrNull(stmt, ++column, instance.getLead(), User::getId); 10.96 - return column; 10.97 - } 10.98 - 10.99 - @Override 10.100 - public void save(Component instance, Project project) throws SQLException { 10.101 - int column = setColumns(insert, instance); 10.102 - insert.setInt(++column, project.getId()); 10.103 - insert.executeUpdate(); 10.104 - } 10.105 - 10.106 - @Override 10.107 - public boolean update(Component instance) throws SQLException { 10.108 - if (instance.getId() < 0) return false; 10.109 - int column = setColumns(update, instance); 10.110 - update.setInt(++column, instance.getId()); 10.111 - return update.executeUpdate() > 0; 10.112 - } 10.113 - 10.114 - 10.115 - @Override 10.116 - public List<Component> list(Project project) throws SQLException { 10.117 - list.setInt(1, project.getId()); 10.118 - return Functions.list(list, PGComponentDao::mapColumns); 10.119 - } 10.120 - 10.121 - @Override 10.122 - public Component find(int id) throws SQLException { 10.123 - find.setInt(1, id); 10.124 - return Functions.find(find, PGComponentDao::mapColumns); 10.125 - } 10.126 - 10.127 - @Override 10.128 - public Component findByNode(Project project, String node) throws SQLException { 10.129 - findByNode.setInt(1, project.getId()); 10.130 - findByNode.setString(2, node);; 10.131 - return Functions.find(findByNode, PGComponentDao::mapColumns); 10.132 - } 10.133 -}
11.1 --- a/src/main/java/de/uapcore/lightpit/dao/postgres/PGDataAccessObjects.java Fri Nov 06 10:50:32 2020 +0100 11.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 11.3 @@ -1,76 +0,0 @@ 11.4 -/* 11.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 11.6 - * 11.7 - * Copyright 2018 Mike Becker. All rights reserved. 11.8 - * 11.9 - * Redistribution and use in source and binary forms, with or without 11.10 - * modification, are permitted provided that the following conditions are met: 11.11 - * 11.12 - * 1. Redistributions of source code must retain the above copyright 11.13 - * notice, this list of conditions and the following disclaimer. 11.14 - * 11.15 - * 2. Redistributions in binary form must reproduce the above copyright 11.16 - * notice, this list of conditions and the following disclaimer in the 11.17 - * documentation and/or other materials provided with the distribution. 11.18 - * 11.19 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 11.20 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 11.21 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 11.22 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 11.23 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 11.24 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 11.25 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 11.26 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 11.27 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 11.28 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 11.29 - * POSSIBILITY OF SUCH DAMAGE. 11.30 - * 11.31 - */ 11.32 -package de.uapcore.lightpit.dao.postgres; 11.33 - 11.34 -import de.uapcore.lightpit.dao.*; 11.35 - 11.36 -import java.sql.Connection; 11.37 -import java.sql.SQLException; 11.38 - 11.39 -public class PGDataAccessObjects implements DataAccessObjects { 11.40 - 11.41 - private final UserDao userDao; 11.42 - private final ProjectDao projectDao; 11.43 - private final VersionDao versionDao; 11.44 - private final ComponentDao componentDao; 11.45 - private final IssueDao issueDao; 11.46 - 11.47 - public PGDataAccessObjects(Connection connection) throws SQLException { 11.48 - userDao = new PGUserDao(connection); 11.49 - projectDao = new PGProjectDao(connection); 11.50 - versionDao = new PGVersionDao(connection); 11.51 - componentDao = new PGComponentDao(connection); 11.52 - issueDao = new PGIssueDao(connection); 11.53 - } 11.54 - 11.55 - @Override 11.56 - public UserDao getUserDao() { 11.57 - return userDao; 11.58 - } 11.59 - 11.60 - @Override 11.61 - public ProjectDao getProjectDao() { 11.62 - return projectDao; 11.63 - } 11.64 - 11.65 - @Override 11.66 - public ComponentDao getComponentDao() { 11.67 - return componentDao; 11.68 - } 11.69 - 11.70 - @Override 11.71 - public VersionDao getVersionDao() { 11.72 - return versionDao; 11.73 - } 11.74 - 11.75 - @Override 11.76 - public IssueDao getIssueDao() { 11.77 - return issueDao; 11.78 - } 11.79 -}
12.1 --- a/src/main/java/de/uapcore/lightpit/dao/postgres/PGIssueDao.java Fri Nov 06 10:50:32 2020 +0100 12.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 12.3 @@ -1,306 +0,0 @@ 12.4 -/* 12.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 12.6 - * 12.7 - * Copyright 2018 Mike Becker. All rights reserved. 12.8 - * 12.9 - * Redistribution and use in source and binary forms, with or without 12.10 - * modification, are permitted provided that the following conditions are met: 12.11 - * 12.12 - * 1. Redistributions of source code must retain the above copyright 12.13 - * notice, this list of conditions and the following disclaimer. 12.14 - * 12.15 - * 2. Redistributions in binary form must reproduce the above copyright 12.16 - * notice, this list of conditions and the following disclaimer in the 12.17 - * documentation and/or other materials provided with the distribution. 12.18 - * 12.19 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 12.20 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 12.21 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 12.22 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 12.23 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 12.24 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 12.25 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 12.26 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 12.27 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 12.28 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 12.29 - * POSSIBILITY OF SUCH DAMAGE. 12.30 - * 12.31 - */ 12.32 -package de.uapcore.lightpit.dao.postgres; 12.33 - 12.34 -import de.uapcore.lightpit.dao.IssueDao; 12.35 -import de.uapcore.lightpit.entities.*; 12.36 - 12.37 -import java.sql.*; 12.38 -import java.util.ArrayList; 12.39 -import java.util.List; 12.40 -import java.util.Objects; 12.41 -import java.util.Optional; 12.42 - 12.43 -import static de.uapcore.lightpit.dao.Functions.*; 12.44 - 12.45 -public final class PGIssueDao implements IssueDao { 12.46 - 12.47 - private final PreparedStatement insert, update, list, listForVersion, find; 12.48 - private final PreparedStatement affectedVersions, resolvedVersions; 12.49 - private final PreparedStatement clearAffected, clearResolved; 12.50 - private final PreparedStatement insertAffected, insertResolved; 12.51 - private final PreparedStatement insertComment, updateComment, listComments; 12.52 - 12.53 - public PGIssueDao(Connection connection) throws SQLException { 12.54 - final var query = "select issueid, i.project, p.name as projectname, p.node as projectnode, "+ 12.55 - "component, c.name as componentname, c.node as componentnode, " + 12.56 - "status, category, subject, i.description, " + 12.57 - "userid, username, givenname, lastname, mail, " + 12.58 - "created, updated, eta " + 12.59 - "from lpit_issue i " + 12.60 - "join lpit_project p on i.project = projectid " + 12.61 - "left join lpit_component c on component = c.id " + 12.62 - "left join lpit_user on userid = assignee "; 12.63 - 12.64 - list = connection.prepareStatement(query + 12.65 - "where i.project = ? and coalesce(component, -1) = coalesce(?, component, -1)"); 12.66 - 12.67 - listForVersion = connection.prepareStatement( 12.68 - "with issue_version as ( "+ 12.69 - "select issueid, versionid from lpit_issue_affected_version union "+ 12.70 - "select issueid, versionid from lpit_issue_resolved_version) "+ 12.71 - query + 12.72 - "left join issue_version using (issueid) "+ 12.73 - "where i.project = ? "+ 12.74 - "and coalesce(versionid,-1) = ? and coalesce(component, -1) = coalesce(?, component, -1)" 12.75 - ); 12.76 - 12.77 - find = connection.prepareStatement(query + "where issueid = ? "); 12.78 - 12.79 - insert = connection.prepareStatement( 12.80 - "insert into lpit_issue (project, component, status, category, subject, description, assignee, eta) " + 12.81 - "values (?, ?, ?::issue_status, ?::issue_category, ?, ?, ?, ?) returning issueid" 12.82 - ); 12.83 - update = connection.prepareStatement( 12.84 - "update lpit_issue set " + 12.85 - "updated = now(), component = ?, status = ?::issue_status, category = ?::issue_category, " + 12.86 - "subject = ?, description = ?, assignee = ?, eta = ? where issueid = ?" 12.87 - ); 12.88 - 12.89 - affectedVersions = connection.prepareStatement( 12.90 - "select versionid, name, status, ordinal " + 12.91 - "from lpit_version join lpit_issue_affected_version using (versionid) " + 12.92 - "where issueid = ? " + 12.93 - "order by ordinal, name" 12.94 - ); 12.95 - clearAffected = connection.prepareStatement("delete from lpit_issue_affected_version where issueid = ?"); 12.96 - insertAffected = connection.prepareStatement("insert into lpit_issue_affected_version (issueid, versionid) values (?,?)"); 12.97 - 12.98 - resolvedVersions = connection.prepareStatement( 12.99 - "select versionid, name, status, ordinal " + 12.100 - "from lpit_version v join lpit_issue_resolved_version using (versionid) " + 12.101 - "where issueid = ? " + 12.102 - "order by ordinal, name" 12.103 - ); 12.104 - clearResolved = connection.prepareStatement("delete from lpit_issue_resolved_version where issueid = ?"); 12.105 - insertResolved = connection.prepareStatement("insert into lpit_issue_resolved_version (issueid, versionid) values (?,?)"); 12.106 - 12.107 - insertComment = connection.prepareStatement( 12.108 - "insert into lpit_issue_comment (issueid, comment, userid) values (?, ? ,?)" 12.109 - ); 12.110 - updateComment = connection.prepareStatement( 12.111 - "update lpit_issue_comment set comment = ?, updated = now(), updatecount = updatecount+1 where commentid = ?" 12.112 - ); 12.113 - listComments = connection.prepareStatement( 12.114 - "select * from lpit_issue_comment left join lpit_user using (userid) where issueid = ? order by created" 12.115 - ); 12.116 - } 12.117 - 12.118 - private Issue mapColumns(ResultSet result) throws SQLException { 12.119 - final var project = new Project(result.getInt("project")); 12.120 - project.setName(result.getString("projectname")); 12.121 - project.setNode(result.getString("projectnode")); 12.122 - var component = new Component(result.getInt("component")); 12.123 - if (result.wasNull()) { 12.124 - component = null; 12.125 - } else { 12.126 - component.setName(result.getString("componentname")); 12.127 - component.setNode(result.getString("componentnode")); 12.128 - } 12.129 - final var issue = new Issue(result.getInt("issueid")); 12.130 - issue.setProject(project); 12.131 - issue.setComponent(component); 12.132 - issue.setStatus(IssueStatus.valueOf(result.getString("status"))); 12.133 - issue.setCategory(IssueCategory.valueOf(result.getString("category"))); 12.134 - issue.setSubject(result.getString("subject")); 12.135 - issue.setDescription(result.getString("description")); 12.136 - issue.setAssignee(PGUserDao.mapColumns(result)); 12.137 - issue.setCreated(result.getTimestamp("created")); 12.138 - issue.setUpdated(result.getTimestamp("updated")); 12.139 - issue.setEta(result.getDate("eta")); 12.140 - return issue; 12.141 - } 12.142 - 12.143 - private Version mapVersion(ResultSet result) throws SQLException { 12.144 - final var version = new Version(result.getInt("versionid")); 12.145 - version.setName(result.getString("name")); 12.146 - version.setOrdinal(result.getInt("ordinal")); 12.147 - version.setStatus(VersionStatus.valueOf(result.getString("status"))); 12.148 - return version; 12.149 - } 12.150 - 12.151 - private void updateVersionLists(Issue instance) throws SQLException { 12.152 - clearAffected.setInt(1, instance.getId()); 12.153 - clearResolved.setInt(1, instance.getId()); 12.154 - insertAffected.setInt(1, instance.getId()); 12.155 - insertResolved.setInt(1, instance.getId()); 12.156 - clearAffected.executeUpdate(); 12.157 - clearResolved.executeUpdate(); 12.158 - for (Version v : instance.getAffectedVersions()) { 12.159 - insertAffected.setInt(2, v.getId()); 12.160 - insertAffected.executeUpdate(); 12.161 - } 12.162 - for (Version v : instance.getResolvedVersions()) { 12.163 - insertResolved.setInt(2, v.getId()); 12.164 - insertResolved.executeUpdate(); 12.165 - } 12.166 - } 12.167 - 12.168 - private int setData(PreparedStatement stmt, int column, Issue instance) throws SQLException { 12.169 - setForeignKeyOrNull(stmt, ++column, instance.getComponent(), Component::getId); 12.170 - stmt.setString(++column, instance.getStatus().name()); 12.171 - stmt.setString(++column, instance.getCategory().name()); 12.172 - stmt.setString(++column, instance.getSubject()); 12.173 - setStringOrNull(stmt, ++column, instance.getDescription()); 12.174 - setForeignKeyOrNull(stmt, ++column, instance.getAssignee(), User::getId); 12.175 - setDateOrNull(stmt, ++column, instance.getEta()); 12.176 - return column; 12.177 - } 12.178 - 12.179 - @Override 12.180 - public void save(Issue instance, Project project) throws SQLException { 12.181 - Objects.requireNonNull(instance.getSubject()); 12.182 - instance.setProject(project); 12.183 - int column = 0; 12.184 - insert.setInt(++column, instance.getProject().getId()); 12.185 - setData(insert, column, instance); 12.186 - // insert and retrieve the ID 12.187 - final var rs = insert.executeQuery(); 12.188 - rs.next(); 12.189 - instance.setId(rs.getInt(1)); 12.190 - updateVersionLists(instance); 12.191 - } 12.192 - 12.193 - @Override 12.194 - public boolean update(Issue instance) throws SQLException { 12.195 - if (instance.getId() < 0) return false; 12.196 - Objects.requireNonNull(instance.getSubject()); 12.197 - int column = setData(update, 0, instance); 12.198 - update.setInt(++column, instance.getId()); 12.199 - boolean success = update.executeUpdate() > 0; 12.200 - if (success) { 12.201 - updateVersionLists(instance); 12.202 - return true; 12.203 - } else { 12.204 - return false; 12.205 - } 12.206 - } 12.207 - 12.208 - private List<Issue> executeQuery(PreparedStatement query) throws SQLException { 12.209 - List<Issue> issues = new ArrayList<>(); 12.210 - try (var result = query.executeQuery()) { 12.211 - while (result.next()) { 12.212 - issues.add(mapColumns(result)); 12.213 - } 12.214 - } 12.215 - return issues; 12.216 - } 12.217 - 12.218 - @Override 12.219 - public List<Issue> list(Project project) throws SQLException { 12.220 - list.setInt(1, project.getId()); 12.221 - list.setNull(2, Types.INTEGER); 12.222 - return executeQuery(list); 12.223 - } 12.224 - 12.225 - @Override 12.226 - public List<Issue> list(Project project, Component component, Version version) throws SQLException { 12.227 - listForVersion.setInt(1, project.getId()); 12.228 - listForVersion.setInt(2, Optional.ofNullable(version).map(Version::getId).orElse(-1)); 12.229 - listForVersion.setInt(3, Optional.ofNullable(component).map(Component::getId).orElse(-1)); 12.230 - return executeQuery(listForVersion); 12.231 - } 12.232 - 12.233 - @Override 12.234 - public List<Issue> list(Project project, Version version) throws SQLException { 12.235 - listForVersion.setInt(1, project.getId()); 12.236 - listForVersion.setInt(2, Optional.ofNullable(version).map(Version::getId).orElse(-1)); 12.237 - listForVersion.setNull(3, Types.INTEGER); 12.238 - return executeQuery(listForVersion); 12.239 - } 12.240 - 12.241 - @Override 12.242 - public List<Issue> list(Project project, Component component) throws SQLException { 12.243 - list.setInt(1, project.getId()); 12.244 - list.setInt(2, Optional.ofNullable(component).map(Component::getId).orElse(-1)); 12.245 - return executeQuery(list); 12.246 - } 12.247 - 12.248 - @Override 12.249 - public Issue find(int id) throws SQLException { 12.250 - find.setInt(1, id); 12.251 - try (var result = find.executeQuery()) { 12.252 - if (result.next()) { 12.253 - return mapColumns(result); 12.254 - } else { 12.255 - return null; 12.256 - } 12.257 - } 12.258 - } 12.259 - 12.260 - private List<Version> listVersions(PreparedStatement stmt, Issue issue) throws SQLException { 12.261 - stmt.setInt(1, issue.getId()); 12.262 - List<Version> versions = new ArrayList<>(); 12.263 - try (var result = stmt.executeQuery()) { 12.264 - while (result.next()) { 12.265 - versions.add(mapVersion(result)); 12.266 - } 12.267 - } 12.268 - return versions; 12.269 - } 12.270 - 12.271 - @Override 12.272 - public void joinVersionInformation(Issue issue) throws SQLException { 12.273 - Objects.requireNonNull(issue.getProject()); 12.274 - issue.setAffectedVersions(listVersions(affectedVersions, issue)); 12.275 - issue.setResolvedVersions(listVersions(resolvedVersions, issue)); 12.276 - } 12.277 - 12.278 - @Override 12.279 - public List<IssueComment> listComments(Issue issue) throws SQLException { 12.280 - listComments.setInt(1, issue.getId()); 12.281 - List<IssueComment> comments = new ArrayList<>(); 12.282 - try (var result = listComments.executeQuery()) { 12.283 - while (result.next()) { 12.284 - final var comment = new IssueComment(result.getInt("commentid")); 12.285 - comment.setCreated(result.getTimestamp("created")); 12.286 - comment.setUpdated(result.getTimestamp("updated")); 12.287 - comment.setUpdateCount(result.getInt("updatecount")); 12.288 - comment.setComment(result.getString("comment")); 12.289 - comment.setAuthor(PGUserDao.mapColumns(result)); 12.290 - comments.add(comment); 12.291 - } 12.292 - } 12.293 - return comments; 12.294 - } 12.295 - 12.296 - @Override 12.297 - public void saveComment(Issue issue, IssueComment comment) throws SQLException { 12.298 - if (comment.getId() >= 0) { 12.299 - updateComment.setString(1, comment.getComment()); 12.300 - updateComment.setInt(2, comment.getId()); 12.301 - updateComment.execute(); 12.302 - } else { 12.303 - insertComment.setInt(1, issue.getId()); 12.304 - insertComment.setString(2, comment.getComment()); 12.305 - setForeignKeyOrNull(insertComment, 3, comment.getAuthor(), User::getId); 12.306 - insertComment.execute(); 12.307 - } 12.308 - } 12.309 -}
13.1 --- a/src/main/java/de/uapcore/lightpit/dao/postgres/PGProjectDao.java Fri Nov 06 10:50:32 2020 +0100 13.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 13.3 @@ -1,151 +0,0 @@ 13.4 -/* 13.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 13.6 - * 13.7 - * Copyright 2018 Mike Becker. All rights reserved. 13.8 - * 13.9 - * Redistribution and use in source and binary forms, with or without 13.10 - * modification, are permitted provided that the following conditions are met: 13.11 - * 13.12 - * 1. Redistributions of source code must retain the above copyright 13.13 - * notice, this list of conditions and the following disclaimer. 13.14 - * 13.15 - * 2. Redistributions in binary form must reproduce the above copyright 13.16 - * notice, this list of conditions and the following disclaimer in the 13.17 - * documentation and/or other materials provided with the distribution. 13.18 - * 13.19 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 13.20 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 13.21 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 13.22 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 13.23 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 13.24 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 13.25 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 13.26 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 13.27 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 13.28 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 13.29 - * POSSIBILITY OF SUCH DAMAGE. 13.30 - * 13.31 - */ 13.32 -package de.uapcore.lightpit.dao.postgres; 13.33 - 13.34 -import de.uapcore.lightpit.dao.Functions; 13.35 -import de.uapcore.lightpit.dao.ProjectDao; 13.36 -import de.uapcore.lightpit.entities.IssueSummary; 13.37 -import de.uapcore.lightpit.entities.Project; 13.38 -import de.uapcore.lightpit.entities.User; 13.39 - 13.40 -import java.sql.Connection; 13.41 -import java.sql.PreparedStatement; 13.42 -import java.sql.ResultSet; 13.43 -import java.sql.SQLException; 13.44 -import java.util.List; 13.45 - 13.46 -import static de.uapcore.lightpit.dao.Functions.setForeignKeyOrNull; 13.47 -import static de.uapcore.lightpit.dao.Functions.setStringOrNull; 13.48 - 13.49 -public final class PGProjectDao implements ProjectDao { 13.50 - 13.51 - private final PreparedStatement insert, update, list, find, findByNode; 13.52 - private final PreparedStatement issue_summary; 13.53 - 13.54 - public PGProjectDao(Connection connection) throws SQLException { 13.55 - final var query = "select projectid, name, node, description, repourl, " + 13.56 - "userid, username, lastname, givenname, mail " + 13.57 - "from lpit_project " + 13.58 - "left join lpit_user owner on lpit_project.owner = owner.userid "; 13.59 - 13.60 - list = connection.prepareStatement(query + " order by name"); 13.61 - 13.62 - find = connection.prepareStatement(query + " where projectid = ?"); 13.63 - findByNode = connection.prepareStatement(query + " where node = ?"); 13.64 - 13.65 - issue_summary = connection.prepareStatement( 13.66 - "select phase, count(*) as total "+ 13.67 - "from lpit_issue " + 13.68 - "join lpit_issue_phases using(status) " + 13.69 - "where project = ? "+ 13.70 - "group by phase " 13.71 - ); 13.72 - 13.73 - insert = connection.prepareStatement( 13.74 - "insert into lpit_project (name, node, description, repourl, owner) values (?, ?, ?, ?, ?)" 13.75 - ); 13.76 - update = connection.prepareStatement( 13.77 - "update lpit_project set name = ?, node = ?, description = ?, repourl = ?, owner = ? where projectid = ?" 13.78 - ); 13.79 - } 13.80 - 13.81 - private static Project mapColumns(ResultSet result) throws SQLException { 13.82 - final var proj = new Project(result.getInt("projectid")); 13.83 - proj.setName(result.getString("name")); 13.84 - proj.setNode(result.getString("node")); 13.85 - proj.setDescription(result.getString("description")); 13.86 - proj.setRepoUrl(result.getString("repourl")); 13.87 - proj.setOwner(PGUserDao.mapColumns(result)); 13.88 - 13.89 - return proj; 13.90 - } 13.91 - 13.92 - public IssueSummary getIssueSummary(Project project) throws SQLException { 13.93 - issue_summary.setInt(1, project.getId()); 13.94 - final var result = issue_summary.executeQuery(); 13.95 - final var summary = new IssueSummary(); 13.96 - while (result.next()) { 13.97 - final var phase = result.getInt("phase"); 13.98 - final var total = result.getInt("total"); 13.99 - switch(phase) { 13.100 - case 0: 13.101 - summary.setOpen(total); 13.102 - break; 13.103 - case 1: 13.104 - summary.setActive(total); 13.105 - break; 13.106 - case 2: 13.107 - summary.setDone(total); 13.108 - break; 13.109 - } 13.110 - } 13.111 - return summary; 13.112 - } 13.113 - 13.114 - private static int setColumns(PreparedStatement stmt, Project instance) throws SQLException { 13.115 - int column = 0; 13.116 - stmt.setString(++column, instance.getName()); 13.117 - stmt.setString(++column, instance.getNode()); 13.118 - setStringOrNull(stmt, ++column, instance.getDescription()); 13.119 - setStringOrNull(stmt, ++column, instance.getRepoUrl()); 13.120 - setForeignKeyOrNull(stmt, ++column, instance.getOwner(), User::getId); 13.121 - return column; 13.122 - } 13.123 - 13.124 - @Override 13.125 - public void save(Project instance) throws SQLException { 13.126 - setColumns(insert, instance); 13.127 - insert.executeUpdate(); 13.128 - } 13.129 - 13.130 - @Override 13.131 - public boolean update(Project instance) throws SQLException { 13.132 - if (instance.getId() < 0) return false; 13.133 - int column = setColumns(update, instance); 13.134 - update.setInt(++column, instance.getId()); 13.135 - return update.executeUpdate() > 0; 13.136 - } 13.137 - 13.138 - @Override 13.139 - public List<Project> list() throws SQLException { 13.140 - return Functions.list(list, PGProjectDao::mapColumns); 13.141 - } 13.142 - 13.143 - @Override 13.144 - public Project find(int id) throws SQLException { 13.145 - find.setInt(1, id); 13.146 - return Functions.find(find, PGProjectDao::mapColumns); 13.147 - } 13.148 - 13.149 - @Override 13.150 - public Project findByNode(String node) throws SQLException { 13.151 - findByNode.setString(1, node); 13.152 - return Functions.find(findByNode, PGProjectDao::mapColumns); 13.153 - } 13.154 -}
14.1 --- a/src/main/java/de/uapcore/lightpit/dao/postgres/PGUserDao.java Fri Nov 06 10:50:32 2020 +0100 14.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 14.3 @@ -1,132 +0,0 @@ 14.4 -/* 14.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 14.6 - * 14.7 - * Copyright 2018 Mike Becker. All rights reserved. 14.8 - * 14.9 - * Redistribution and use in source and binary forms, with or without 14.10 - * modification, are permitted provided that the following conditions are met: 14.11 - * 14.12 - * 1. Redistributions of source code must retain the above copyright 14.13 - * notice, this list of conditions and the following disclaimer. 14.14 - * 14.15 - * 2. Redistributions in binary form must reproduce the above copyright 14.16 - * notice, this list of conditions and the following disclaimer in the 14.17 - * documentation and/or other materials provided with the distribution. 14.18 - * 14.19 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 14.20 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14.21 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 14.22 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 14.23 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 14.24 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 14.25 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 14.26 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 14.27 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 14.28 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 14.29 - * POSSIBILITY OF SUCH DAMAGE. 14.30 - * 14.31 - */ 14.32 -package de.uapcore.lightpit.dao.postgres; 14.33 - 14.34 -import de.uapcore.lightpit.dao.UserDao; 14.35 -import de.uapcore.lightpit.entities.User; 14.36 - 14.37 -import java.sql.Connection; 14.38 -import java.sql.PreparedStatement; 14.39 -import java.sql.ResultSet; 14.40 -import java.sql.SQLException; 14.41 -import java.util.ArrayList; 14.42 -import java.util.List; 14.43 -import java.util.Objects; 14.44 -import java.util.Optional; 14.45 - 14.46 -import static de.uapcore.lightpit.dao.Functions.getSafeString; 14.47 -import static de.uapcore.lightpit.dao.Functions.setStringOrNull; 14.48 - 14.49 -public final class PGUserDao implements UserDao { 14.50 - 14.51 - private final PreparedStatement insert, update, list, find, findByUsername; 14.52 - 14.53 - public PGUserDao(Connection connection) throws SQLException { 14.54 - list = connection.prepareStatement( 14.55 - "select userid, username, lastname, givenname, mail " + 14.56 - "from lpit_user where userid >= 0 " + 14.57 - "order by username"); 14.58 - find = connection.prepareStatement( 14.59 - "select userid, username, lastname, givenname, mail " + 14.60 - "from lpit_user where userid = ? "); 14.61 - 14.62 - findByUsername = connection.prepareStatement( 14.63 - "select userid, username, lastname, givenname, mail " + 14.64 - "from lpit_user where lower(username) = lower(?) "); 14.65 - 14.66 - insert = connection.prepareStatement("insert into lpit_user (username, lastname, givenname, mail) values (?, ?, ?, ?)"); 14.67 - update = connection.prepareStatement("update lpit_user set lastname = ?, givenname = ?, mail = ? where userid = ?"); 14.68 - } 14.69 - 14.70 - static User mapColumns(ResultSet result) throws SQLException { 14.71 - final int id = result.getInt("userid"); 14.72 - if (id == 0) return null; 14.73 - final var user = new User(id); 14.74 - user.setUsername(result.getString("username")); 14.75 - user.setGivenname(getSafeString(result, "givenname")); 14.76 - user.setLastname(getSafeString(result, "lastname")); 14.77 - user.setMail(getSafeString(result, "mail")); 14.78 - return user; 14.79 - } 14.80 - 14.81 - @Override 14.82 - public void save(User instance) throws SQLException { 14.83 - Objects.requireNonNull(instance.getUsername()); 14.84 - insert.setString(1, instance.getUsername()); 14.85 - setStringOrNull(insert, 2, instance.getLastname()); 14.86 - setStringOrNull(insert, 3, instance.getGivenname()); 14.87 - setStringOrNull(insert, 4, instance.getMail()); 14.88 - insert.executeUpdate(); 14.89 - } 14.90 - 14.91 - @Override 14.92 - public boolean update(User instance) throws SQLException { 14.93 - if (instance.getId() < 0) return false; 14.94 - setStringOrNull(update, 1, instance.getLastname()); 14.95 - setStringOrNull(update, 2, instance.getGivenname()); 14.96 - setStringOrNull(update, 3, instance.getMail()); 14.97 - update.setInt(4, instance.getId()); 14.98 - return update.executeUpdate() > 0; 14.99 - } 14.100 - 14.101 - @Override 14.102 - public List<User> list() throws SQLException { 14.103 - List<User> users = new ArrayList<>(); 14.104 - try (var result = list.executeQuery()) { 14.105 - while (result.next()) { 14.106 - users.add(mapColumns(result)); 14.107 - } 14.108 - } 14.109 - return users; 14.110 - } 14.111 - 14.112 - @Override 14.113 - public User find(int id) throws SQLException { 14.114 - find.setInt(1, id); 14.115 - try (var result = find.executeQuery()) { 14.116 - if (result.next()) { 14.117 - return mapColumns(result); 14.118 - } else { 14.119 - return null; 14.120 - } 14.121 - } 14.122 - } 14.123 - 14.124 - @Override 14.125 - public Optional<User> findByUsername(String username) throws SQLException { 14.126 - findByUsername.setString(1, username); 14.127 - try (var result = findByUsername.executeQuery()) { 14.128 - if (result.next()) { 14.129 - return Optional.of(mapColumns(result)); 14.130 - } else { 14.131 - return Optional.empty(); 14.132 - } 14.133 - } 14.134 - } 14.135 -}
15.1 --- a/src/main/java/de/uapcore/lightpit/dao/postgres/PGVersionDao.java Fri Nov 06 10:50:32 2020 +0100 15.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 15.3 @@ -1,114 +0,0 @@ 15.4 -/* 15.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 15.6 - * 15.7 - * Copyright 2018 Mike Becker. All rights reserved. 15.8 - * 15.9 - * Redistribution and use in source and binary forms, with or without 15.10 - * modification, are permitted provided that the following conditions are met: 15.11 - * 15.12 - * 1. Redistributions of source code must retain the above copyright 15.13 - * notice, this list of conditions and the following disclaimer. 15.14 - * 15.15 - * 2. Redistributions in binary form must reproduce the above copyright 15.16 - * notice, this list of conditions and the following disclaimer in the 15.17 - * documentation and/or other materials provided with the distribution. 15.18 - * 15.19 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15.20 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15.21 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 15.22 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 15.23 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 15.24 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 15.25 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 15.26 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 15.27 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 15.28 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 15.29 - * POSSIBILITY OF SUCH DAMAGE. 15.30 - * 15.31 - */ 15.32 -package de.uapcore.lightpit.dao.postgres; 15.33 - 15.34 -import de.uapcore.lightpit.dao.Functions; 15.35 -import de.uapcore.lightpit.dao.VersionDao; 15.36 -import de.uapcore.lightpit.entities.Project; 15.37 -import de.uapcore.lightpit.entities.Version; 15.38 -import de.uapcore.lightpit.entities.VersionStatus; 15.39 - 15.40 -import java.sql.Connection; 15.41 -import java.sql.PreparedStatement; 15.42 -import java.sql.ResultSet; 15.43 -import java.sql.SQLException; 15.44 -import java.util.List; 15.45 - 15.46 -public final class PGVersionDao implements VersionDao { 15.47 - 15.48 - private final PreparedStatement insert, update, list, find, findByNode; 15.49 - 15.50 - public PGVersionDao(Connection connection) throws SQLException { 15.51 - final var query = "select versionid, project, name, node, ordinal, status from lpit_version"; 15.52 - 15.53 - list = connection.prepareStatement(query + " where project = ? " + 15.54 - "order by ordinal desc, lower(name) desc"); 15.55 - find = connection.prepareStatement(query + " where versionid = ?"); 15.56 - findByNode = connection.prepareStatement(query + " where project = ? and node = ?"); 15.57 - 15.58 - insert = connection.prepareStatement( 15.59 - "insert into lpit_version (name, node, ordinal, status, project) values (?, ?, ?, ?::version_status, ?)" 15.60 - ); 15.61 - update = connection.prepareStatement( 15.62 - "update lpit_version set name = ?, node = ?, ordinal = ?, status = ?::version_status where versionid = ?" 15.63 - ); 15.64 - } 15.65 - 15.66 - private static Version mapColumns(ResultSet result) throws SQLException { 15.67 - final var version = new Version(result.getInt("versionid")); 15.68 - version.setName(result.getString("name")); 15.69 - version.setNode(result.getString("node")); 15.70 - version.setOrdinal(result.getInt("ordinal")); 15.71 - version.setStatus(VersionStatus.valueOf(result.getString("status"))); 15.72 - return version; 15.73 - } 15.74 - 15.75 - private static int setFields(PreparedStatement stmt, Version instance) throws SQLException { 15.76 - int column = 0; 15.77 - stmt.setString(++column, instance.getName()); 15.78 - stmt.setString(++column, instance.getNode()); 15.79 - stmt.setInt(++column, instance.getOrdinal()); 15.80 - stmt.setString(++column, instance.getStatus().name()); 15.81 - return column; 15.82 - } 15.83 - 15.84 - @Override 15.85 - public void save(Version instance, Project project) throws SQLException { 15.86 - int column = setFields(insert, instance); 15.87 - insert.setInt(++column, project.getId()); 15.88 - insert.executeUpdate(); 15.89 - } 15.90 - 15.91 - @Override 15.92 - public boolean update(Version instance) throws SQLException { 15.93 - if (instance.getId() < 0) return false; 15.94 - int column = setFields(update, instance); 15.95 - update.setInt(++column, instance.getId()); 15.96 - return update.executeUpdate() > 0; 15.97 - } 15.98 - 15.99 - @Override 15.100 - public List<Version> list(Project project) throws SQLException { 15.101 - list.setInt(1, project.getId()); 15.102 - return Functions.list(list, PGVersionDao::mapColumns); 15.103 - } 15.104 - 15.105 - @Override 15.106 - public Version find(int id) throws SQLException { 15.107 - find.setInt(1, id); 15.108 - return Functions.find(find, PGVersionDao::mapColumns); 15.109 - } 15.110 - 15.111 - @Override 15.112 - public Version findByNode(Project project, String node) throws SQLException { 15.113 - findByNode.setInt(1, project.getId()); 15.114 - findByNode.setString(2, node);; 15.115 - return Functions.find(findByNode, PGVersionDao::mapColumns); 15.116 - } 15.117 -}
16.1 --- a/src/main/java/de/uapcore/lightpit/modules/ProjectsModule.java Fri Nov 06 10:50:32 2020 +0100 16.2 +++ b/src/main/java/de/uapcore/lightpit/modules/ProjectsModule.java Thu Nov 19 13:58:54 2020 +0100 16.3 @@ -30,7 +30,7 @@ 16.4 16.5 16.6 import de.uapcore.lightpit.*; 16.7 -import de.uapcore.lightpit.dao.DataAccessObjects; 16.8 +import de.uapcore.lightpit.dao.DaoProvider; 16.9 import de.uapcore.lightpit.entities.*; 16.10 import de.uapcore.lightpit.types.WebColor; 16.11 import de.uapcore.lightpit.viewmodel.*; 16.12 @@ -72,7 +72,7 @@ 16.13 } 16.14 } 16.15 16.16 - private void populate(ProjectView viewModel, PathParameters pathParameters, DataAccessObjects dao) throws SQLException { 16.17 + private void populate(ProjectView viewModel, PathParameters pathParameters, DaoProvider dao) throws SQLException { 16.18 final var projectDao = dao.getProjectDao(); 16.19 final var versionDao = dao.getVersionDao(); 16.20 final var componentDao = dao.getComponentDao(); 16.21 @@ -97,7 +97,7 @@ 16.22 final var versionNode = pathParameters.get("version"); 16.23 if ("no-version".equals(versionNode)) { 16.24 viewModel.setVersionFilter(ProjectView.NO_VERSION); 16.25 - } else if ("all-versions".equals(versionNode)) { 16.26 + } else if ("all-versions".equals(versionNode) || versionNode == null) { 16.27 viewModel.setVersionFilter(ProjectView.ALL_VERSIONS); 16.28 } else { 16.29 viewModel.setVersionFilter(versionDao.findByNode(project, versionNode)); 16.30 @@ -107,7 +107,7 @@ 16.31 final var componentNode = pathParameters.get("component"); 16.32 if ("no-component".equals(componentNode)) { 16.33 viewModel.setComponentFilter(ProjectView.NO_COMPONENT); 16.34 - } else if ("all-components".equals(componentNode)) { 16.35 + } else if ("all-components".equals(componentNode) || componentNode == null) { 16.36 viewModel.setComponentFilter(ProjectView.ALL_COMPONENTS); 16.37 } else { 16.38 viewModel.setComponentFilter(componentDao.findByNode(project, componentNode)); 16.39 @@ -133,7 +133,7 @@ 16.40 } 16.41 16.42 @RequestMapping(method = HttpMethod.GET) 16.43 - public void index(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException, ServletException, IOException { 16.44 + public void index(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws SQLException, ServletException, IOException { 16.45 final var viewModel = new ProjectView(); 16.46 populate(viewModel, null, dao); 16.47 16.48 @@ -148,13 +148,13 @@ 16.49 forwardView(req, resp, viewModel, "projects"); 16.50 } 16.51 16.52 - private void configureProjectEditor(ProjectEditView viewModel, Project project, DataAccessObjects dao) throws SQLException { 16.53 + private void configureProjectEditor(ProjectEditView viewModel, Project project, DaoProvider dao) throws SQLException { 16.54 viewModel.setProject(project); 16.55 viewModel.setUsers(dao.getUserDao().list()); 16.56 } 16.57 16.58 @RequestMapping(requestPath = "$project/edit", method = HttpMethod.GET) 16.59 - public void edit(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParams, DataAccessObjects dao) throws IOException, SQLException, ServletException { 16.60 + public void edit(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParams, DaoProvider dao) throws IOException, SQLException, ServletException { 16.61 final var viewModel = new ProjectEditView(); 16.62 populate(viewModel, pathParams, dao); 16.63 16.64 @@ -168,7 +168,7 @@ 16.65 } 16.66 16.67 @RequestMapping(requestPath = "create", method = HttpMethod.GET) 16.68 - public void create(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException, ServletException, IOException { 16.69 + public void create(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws SQLException, ServletException, IOException { 16.70 final var viewModel = new ProjectEditView(); 16.71 populate(viewModel, null, dao); 16.72 configureProjectEditor(viewModel, new Project(-1), dao); 16.73 @@ -176,7 +176,7 @@ 16.74 } 16.75 16.76 @RequestMapping(requestPath = "commit", method = HttpMethod.POST) 16.77 - public void commit(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws IOException, ServletException { 16.78 + public void commit(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws IOException, ServletException { 16.79 16.80 try { 16.81 final var project = new Project(getParameter(req, Integer.class, "pid").orElseThrow()); 16.82 @@ -191,21 +191,27 @@ 16.83 ownerId -> ownerId >= 0 ? new User(ownerId) : null 16.84 ).ifPresent(project::setOwner); 16.85 16.86 - dao.getProjectDao().saveOrUpdate(project); 16.87 + final var projectDao = dao.getProjectDao(); 16.88 + if (project.getId() > 0) { 16.89 + // TODO: unused return value 16.90 + projectDao.update(project); 16.91 + } else { 16.92 + projectDao.save(project); 16.93 + } 16.94 16.95 setRedirectLocation(req, "./projects/"); 16.96 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); 16.97 LOG.debug("Successfully updated project {}", project.getName()); 16.98 16.99 renderSite(req, resp); 16.100 - } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) { 16.101 + } catch (NoSuchElementException | IllegalArgumentException ex) { 16.102 resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED); 16.103 // TODO: implement - fix issue #21 16.104 } 16.105 } 16.106 16.107 @RequestMapping(requestPath = "$project/$component/$version/issues/", method = HttpMethod.GET) 16.108 - public void issues(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParams, DataAccessObjects dao) throws SQLException, IOException, ServletException { 16.109 + public void issues(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParams, DaoProvider dao) throws SQLException, IOException, ServletException { 16.110 final var viewModel = new ProjectDetailsView(); 16.111 populate(viewModel, pathParams, dao); 16.112 16.113 @@ -263,7 +269,7 @@ 16.114 } 16.115 16.116 @RequestMapping(requestPath = "$project/versions/", method = HttpMethod.GET) 16.117 - public void versions(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException, ServletException { 16.118 + public void versions(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException { 16.119 final var viewModel = new VersionsView(); 16.120 populate(viewModel, pathParameters, dao); 16.121 16.122 @@ -282,7 +288,7 @@ 16.123 } 16.124 16.125 @RequestMapping(requestPath = "$project/versions/$version/edit", method = HttpMethod.GET) 16.126 - public void editVersion(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException, ServletException { 16.127 + public void editVersion(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException { 16.128 final var viewModel = new VersionEditView(); 16.129 populate(viewModel, pathParameters, dao); 16.130 16.131 @@ -297,7 +303,7 @@ 16.132 } 16.133 16.134 @RequestMapping(requestPath = "$project/create-version", method = HttpMethod.GET) 16.135 - public void createVersion(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException, ServletException { 16.136 + public void createVersion(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException { 16.137 final var viewModel = new VersionEditView(); 16.138 populate(viewModel, pathParameters, dao); 16.139 16.140 @@ -312,7 +318,7 @@ 16.141 } 16.142 16.143 @RequestMapping(requestPath = "commit-version", method = HttpMethod.POST) 16.144 - public void commitVersion(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws IOException, ServletException { 16.145 + public void commitVersion(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws IOException, ServletException { 16.146 16.147 try { 16.148 final var project = dao.getProjectDao().find(getParameter(req, Integer.class, "pid").orElseThrow()); 16.149 @@ -329,20 +335,27 @@ 16.150 16.151 getParameter(req, Integer.class, "ordinal").ifPresent(version::setOrdinal); 16.152 version.setStatus(VersionStatus.valueOf(getParameter(req, String.class, "status").orElseThrow())); 16.153 - dao.getVersionDao().saveOrUpdate(version, project); 16.154 + 16.155 + final var versionDao = dao.getVersionDao(); 16.156 + if (version.getId() > 0) { 16.157 + // TODO: use return value 16.158 + versionDao.update(version); 16.159 + } else { 16.160 + versionDao.save(version, project); 16.161 + } 16.162 16.163 setRedirectLocation(req, "./projects/" + project.getNode() + "/versions/"); 16.164 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); 16.165 16.166 renderSite(req, resp); 16.167 - } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) { 16.168 + } catch (NoSuchElementException | IllegalArgumentException ex) { 16.169 resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED); 16.170 // TODO: implement - fix issue #21 16.171 } 16.172 } 16.173 16.174 @RequestMapping(requestPath = "$project/components/", method = HttpMethod.GET) 16.175 - public void components(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException, ServletException { 16.176 + public void components(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException { 16.177 final var viewModel = new ComponentsView(); 16.178 populate(viewModel, pathParameters, dao); 16.179 16.180 @@ -360,7 +373,7 @@ 16.181 } 16.182 16.183 @RequestMapping(requestPath = "$project/components/$component/edit", method = HttpMethod.GET) 16.184 - public void editComponent(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException, ServletException { 16.185 + public void editComponent(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException { 16.186 final var viewModel = new ComponentEditView(); 16.187 populate(viewModel, pathParameters, dao); 16.188 16.189 @@ -376,7 +389,7 @@ 16.190 } 16.191 16.192 @RequestMapping(requestPath = "$project/create-component", method = HttpMethod.GET) 16.193 - public void createComponent(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException, ServletException { 16.194 + public void createComponent(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException { 16.195 final var viewModel = new ComponentEditView(); 16.196 populate(viewModel, pathParameters, dao); 16.197 16.198 @@ -392,7 +405,7 @@ 16.199 } 16.200 16.201 @RequestMapping(requestPath = "commit-component", method = HttpMethod.POST) 16.202 - public void commitComponent(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws IOException, ServletException { 16.203 + public void commitComponent(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws IOException, ServletException { 16.204 16.205 try { 16.206 final var project = dao.getProjectDao().find(getParameter(req, Integer.class, "pid").orElseThrow()); 16.207 @@ -414,19 +427,25 @@ 16.208 ).ifPresent(component::setLead); 16.209 getParameter(req, String.class, "description").ifPresent(component::setDescription); 16.210 16.211 - dao.getComponentDao().saveOrUpdate(component, project); 16.212 + final var componentDao = dao.getComponentDao(); 16.213 + if (component.getId() > 0) { 16.214 + // TODO: use return value 16.215 + componentDao.update(component); 16.216 + } else { 16.217 + componentDao.save(component, project); 16.218 + } 16.219 16.220 setRedirectLocation(req, "./projects/" + project.getNode() + "/components/"); 16.221 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); 16.222 16.223 renderSite(req, resp); 16.224 - } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) { 16.225 + } catch (NoSuchElementException | IllegalArgumentException ex) { 16.226 resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED); 16.227 // TODO: implement - fix issue #21 16.228 } 16.229 } 16.230 16.231 - private void configureIssueEditor(IssueEditView viewModel, Issue issue, DataAccessObjects dao) throws SQLException { 16.232 + private void configureIssueEditor(IssueEditView viewModel, Issue issue, DaoProvider dao) throws SQLException { 16.233 final var project = viewModel.getProjectInfo().getProject(); 16.234 issue.setProject(project); // automatically set current project for new issues 16.235 viewModel.setIssue(issue); 16.236 @@ -436,7 +455,7 @@ 16.237 } 16.238 16.239 @RequestMapping(requestPath = "$project/issues/$issue/view", method = HttpMethod.GET) 16.240 - public void viewIssue(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException, ServletException { 16.241 + public void viewIssue(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException { 16.242 final var viewModel = new IssueDetailView(); 16.243 populate(viewModel, pathParameters, dao); 16.244 16.245 @@ -462,7 +481,7 @@ 16.246 16.247 // TODO: why should the issue editor be child of $project? 16.248 @RequestMapping(requestPath = "$project/issues/$issue/edit", method = HttpMethod.GET) 16.249 - public void editIssue(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException, ServletException { 16.250 + public void editIssue(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException { 16.251 final var viewModel = new IssueEditView(); 16.252 populate(viewModel, pathParameters, dao); 16.253 16.254 @@ -486,7 +505,7 @@ 16.255 } 16.256 16.257 @RequestMapping(requestPath = "$project/create-issue", method = HttpMethod.GET) 16.258 - public void createIssue(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException, ServletException { 16.259 + public void createIssue(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException { 16.260 final var viewModel = new IssueEditView(); 16.261 populate(viewModel, pathParameters, dao); 16.262 16.263 @@ -504,7 +523,7 @@ 16.264 } 16.265 16.266 @RequestMapping(requestPath = "commit-issue", method = HttpMethod.POST) 16.267 - public void commitIssue(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws IOException, ServletException { 16.268 + public void commitIssue(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws IOException, ServletException { 16.269 try { 16.270 final var issue = new Issue(getParameter(req, Integer.class, "id").orElseThrow()); 16.271 final var componentId = getParameter(req, Integer.class, "component"); 16.272 @@ -549,21 +568,27 @@ 16.273 stream.map(Version::new).collect(Collectors.toList()) 16.274 ).ifPresent(issue::setResolvedVersions); 16.275 16.276 - dao.getIssueDao().saveOrUpdate(issue, issue.getProject()); 16.277 + final var issueDao = dao.getIssueDao(); 16.278 + if (issue.getId() > 0) { 16.279 + // TODO: use return value 16.280 + issueDao.update(issue); 16.281 + } else { 16.282 + issueDao.save(issue, project); 16.283 + } 16.284 16.285 // TODO: fix redirect location 16.286 setRedirectLocation(req, "./projects/" + issue.getProject().getNode()+"/issues/"+issue.getId()+"/view"); 16.287 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); 16.288 16.289 renderSite(req, resp); 16.290 - } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) { 16.291 + } catch (NoSuchElementException | IllegalArgumentException ex) { 16.292 resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED); 16.293 // TODO: implement - fix issue #21 16.294 } 16.295 } 16.296 16.297 @RequestMapping(requestPath = "commit-issue-comment", method = HttpMethod.POST) 16.298 - public void commentIssue(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException, IOException, ServletException { 16.299 + public void commentIssue(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws IOException, ServletException { 16.300 final var issueIdParam = getParameter(req, Integer.class, "issueid"); 16.301 if (issueIdParam.isEmpty()) { 16.302 resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Detected manipulated form."); 16.303 @@ -584,7 +609,7 @@ 16.304 16.305 LOG.debug("User {} is commenting on issue #{}", req.getRemoteUser(), issue.getId()); 16.306 if (req.getRemoteUser() != null) { 16.307 - dao.getUserDao().findByUsername(req.getRemoteUser()).ifPresent(issueComment::setAuthor); 16.308 + Optional.ofNullable(dao.getUserDao().findByUsername(req.getRemoteUser())).ifPresent(issueComment::setAuthor); 16.309 } 16.310 16.311 dao.getIssueDao().saveComment(issue, issueComment); 16.312 @@ -594,7 +619,7 @@ 16.313 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); 16.314 16.315 renderSite(req, resp); 16.316 - } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) { 16.317 + } catch (NoSuchElementException | IllegalArgumentException ex) { 16.318 resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED); 16.319 // TODO: implement - fix issue #21 16.320 }
17.1 --- a/src/main/java/de/uapcore/lightpit/modules/UsersModule.java Fri Nov 06 10:50:32 2020 +0100 17.2 +++ b/src/main/java/de/uapcore/lightpit/modules/UsersModule.java Thu Nov 19 13:58:54 2020 +0100 17.3 @@ -32,7 +32,7 @@ 17.4 import de.uapcore.lightpit.Constants; 17.5 import de.uapcore.lightpit.HttpMethod; 17.6 import de.uapcore.lightpit.RequestMapping; 17.7 -import de.uapcore.lightpit.dao.DataAccessObjects; 17.8 +import de.uapcore.lightpit.dao.DaoProvider; 17.9 import de.uapcore.lightpit.entities.User; 17.10 import de.uapcore.lightpit.viewmodel.UsersEditView; 17.11 import de.uapcore.lightpit.viewmodel.UsersView; 17.12 @@ -61,7 +61,7 @@ 17.13 } 17.14 17.15 @RequestMapping(method = HttpMethod.GET) 17.16 - public void index(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException, ServletException, IOException { 17.17 + public void index(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws SQLException, ServletException, IOException { 17.18 final var userDao = dao.getUserDao(); 17.19 17.20 final var viewModel = new UsersView(); 17.21 @@ -73,7 +73,7 @@ 17.22 } 17.23 17.24 @RequestMapping(requestPath = "edit", method = HttpMethod.GET) 17.25 - public void edit(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException, ServletException, IOException { 17.26 + public void edit(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws SQLException, ServletException, IOException { 17.27 17.28 final var viewModel = new UsersEditView(); 17.29 viewModel.setUser(findByParameter(req, Integer.class, "id", 17.30 @@ -86,7 +86,7 @@ 17.31 } 17.32 17.33 @RequestMapping(requestPath = "commit", method = HttpMethod.POST) 17.34 - public void commit(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws ServletException, IOException { 17.35 + public void commit(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws ServletException, IOException { 17.36 17.37 User user = new User(-1); 17.38 try { 17.39 @@ -96,13 +96,19 @@ 17.40 getParameter(req, String.class, "lastname").ifPresent(user::setLastname); 17.41 getParameter(req, String.class, "mail").ifPresent(user::setMail); 17.42 17.43 - dao.getUserDao().saveOrUpdate(user); 17.44 + final var userDao = dao.getUserDao(); 17.45 + if (user.getId() > 0) { 17.46 + // TODO: unused return value 17.47 + userDao.update(user); 17.48 + } else { 17.49 + userDao.save(user); 17.50 + } 17.51 17.52 setRedirectLocation(req, "./teams/"); 17.53 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); 17.54 17.55 LOG.debug("Successfully updated user {}", user.getUsername()); 17.56 - } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) { 17.57 + } catch (NoSuchElementException | IllegalArgumentException ex) { 17.58 final var viewModel = new UsersEditView(); 17.59 viewModel.setUser(user); 17.60 // TODO: viewModel.setErrorText()
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 18.2 +++ b/src/main/kotlin/de/uapcore/lightpit/dao/AbstractChildEntityDao.kt Thu Nov 19 13:58:54 2020 +0100 18.3 @@ -0,0 +1,64 @@ 18.4 +/* 18.5 + * Copyright 2020 Mike Becker. All rights reserved. 18.6 + * 18.7 + * Redistribution and use in source and binary forms, with or without 18.8 + * modification, are permitted provided that the following conditions are met: 18.9 + * 18.10 + * 1. Redistributions of source code must retain the above copyright 18.11 + * notice, this list of conditions and the following disclaimer. 18.12 + * 18.13 + * 2. Redistributions in binary form must reproduce the above copyright 18.14 + * notice, this list of conditions and the following disclaimer in the 18.15 + * documentation and/or other materials provided with the distribution. 18.16 + * 18.17 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18.18 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18.19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18.20 + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18.21 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18.22 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 18.23 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 18.24 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 18.25 + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 18.26 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 18.27 + * 18.28 + */ 18.29 + 18.30 +package de.uapcore.lightpit.dao 18.31 + 18.32 + 18.33 +abstract class AbstractChildEntityDao<T, P> : AbstractDao<T>() { 18.34 + 18.35 + /** 18.36 + * Lists all entities being a child of the specified parent. 18.37 + * @param parent the parent 18.38 + * @return the list of child instances 18.39 + */ 18.40 + abstract fun list(parent: P): List<T> 18.41 + 18.42 + /** 18.43 + * Finds an entity by its integer ID. 18.44 + * It is not guaranteed that referenced entities are automatically joined. 18.45 + * 18.46 + * @param id the id 18.47 + * @return the entity or null if there is no such entity 18.48 + */ 18.49 + abstract fun find(id: Int): T? 18.50 + 18.51 + /** 18.52 + * Inserts an instance into database. 18.53 + * It is not guaranteed that generated fields will be updated in the instance. 18.54 + * 18.55 + * @param instance the instance to insert 18.56 + * @param parent a reference to the parent 18.57 + */ 18.58 + abstract fun save(instance: T, parent: P) 18.59 + 18.60 + /** 18.61 + * Updates an instance in the database. 18.62 + * 18.63 + * @param instance the instance to update 18.64 + * @return true if an instance has been updated, false if the instance is not present in database 18.65 + */ 18.66 + abstract fun update(instance: T): Boolean 18.67 +}
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 19.2 +++ b/src/main/kotlin/de/uapcore/lightpit/dao/AbstractComponentDao.kt Thu Nov 19 13:58:54 2020 +0100 19.3 @@ -0,0 +1,34 @@ 19.4 +/* 19.5 + * Copyright 2020 Mike Becker. All rights reserved. 19.6 + * 19.7 + * Redistribution and use in source and binary forms, with or without 19.8 + * modification, are permitted provided that the following conditions are met: 19.9 + * 19.10 + * 1. Redistributions of source code must retain the above copyright 19.11 + * notice, this list of conditions and the following disclaimer. 19.12 + * 19.13 + * 2. Redistributions in binary form must reproduce the above copyright 19.14 + * notice, this list of conditions and the following disclaimer in the 19.15 + * documentation and/or other materials provided with the distribution. 19.16 + * 19.17 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19.18 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19.19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19.20 + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19.21 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19.22 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19.23 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 19.24 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 19.25 + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 19.26 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 19.27 + * 19.28 + */ 19.29 + 19.30 +package de.uapcore.lightpit.dao 19.31 + 19.32 +import de.uapcore.lightpit.entities.Component 19.33 +import de.uapcore.lightpit.entities.Project 19.34 + 19.35 +abstract class AbstractComponentDao : AbstractChildEntityDao<Component, Project>() { 19.36 + abstract fun findByNode(parent: Project, node: String): Component? 19.37 +} 19.38 \ No newline at end of file
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/src/main/kotlin/de/uapcore/lightpit/dao/AbstractDao.kt Thu Nov 19 13:58:54 2020 +0100 20.3 @@ -0,0 +1,65 @@ 20.4 +/* 20.5 + * Copyright 2020 Mike Becker. All rights reserved. 20.6 + * 20.7 + * Redistribution and use in source and binary forms, with or without 20.8 + * modification, are permitted provided that the following conditions are met: 20.9 + * 20.10 + * 1. Redistributions of source code must retain the above copyright 20.11 + * notice, this list of conditions and the following disclaimer. 20.12 + * 20.13 + * 2. Redistributions in binary form must reproduce the above copyright 20.14 + * notice, this list of conditions and the following disclaimer in the 20.15 + * documentation and/or other materials provided with the distribution. 20.16 + * 20.17 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20.18 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20.19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20.20 + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20.21 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20.22 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20.23 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20.24 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 20.25 + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 20.26 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 20.27 + * 20.28 + */ 20.29 + 20.30 +package de.uapcore.lightpit.dao 20.31 + 20.32 +import java.sql.PreparedStatement 20.33 +import java.sql.ResultSet 20.34 +import java.sql.Types 20.35 + 20.36 +abstract class AbstractDao<T> { 20.37 + 20.38 + abstract fun mapResult(rs: ResultSet): T 20.39 + 20.40 + protected fun list(stmt: PreparedStatement): List<T> { 20.41 + return sequence { 20.42 + stmt.executeQuery().use { result -> 20.43 + while (result.next()) yield(mapResult(result)) 20.44 + } 20.45 + }.toList() 20.46 + } 20.47 + 20.48 + protected fun find(stmt: PreparedStatement): T? { 20.49 + stmt.executeQuery().use { result -> 20.50 + return if (result.next()) { 20.51 + mapResult(result) 20.52 + } else { 20.53 + null 20.54 + } 20.55 + } 20.56 + } 20.57 + 20.58 + // TODO: create PreparedStatement abstraction that provides some features 20.59 + 20.60 + // TODO: remove the following legacy code helper function 20.61 + protected fun <T> setForeignKeyOrNull(stmt: PreparedStatement, index: Int, instance: T?, keyGetter: (obj: T) -> Int) { 20.62 + if (instance == null) { 20.63 + stmt.setNull(index, Types.INTEGER) 20.64 + } else { 20.65 + stmt.setInt(index, keyGetter(instance)) 20.66 + } 20.67 + } 20.68 +} 20.69 \ No newline at end of file
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 21.2 +++ b/src/main/kotlin/de/uapcore/lightpit/dao/AbstractEntityDao.kt Thu Nov 19 13:58:54 2020 +0100 21.3 @@ -0,0 +1,61 @@ 21.4 +/* 21.5 + * Copyright 2020 Mike Becker. All rights reserved. 21.6 + * 21.7 + * Redistribution and use in source and binary forms, with or without 21.8 + * modification, are permitted provided that the following conditions are met: 21.9 + * 21.10 + * 1. Redistributions of source code must retain the above copyright 21.11 + * notice, this list of conditions and the following disclaimer. 21.12 + * 21.13 + * 2. Redistributions in binary form must reproduce the above copyright 21.14 + * notice, this list of conditions and the following disclaimer in the 21.15 + * documentation and/or other materials provided with the distribution. 21.16 + * 21.17 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21.18 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21.19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21.20 + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21.21 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21.22 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21.23 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21.24 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 21.25 + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 21.26 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 21.27 + * 21.28 + */ 21.29 + 21.30 +package de.uapcore.lightpit.dao 21.31 + 21.32 +abstract class AbstractEntityDao<T> : AbstractDao<T>() { 21.33 + 21.34 + /** 21.35 + * Lists all entities. 21.36 + * @return a list of all entities 21.37 + */ 21.38 + abstract fun list(): List<T> 21.39 + 21.40 + /** 21.41 + * Finds an entity by its integer ID. 21.42 + * It is not guaranteed that referenced entities are automatically joined. 21.43 + * 21.44 + * @param id the id 21.45 + * @return the entity or null if there is no such entity 21.46 + */ 21.47 + abstract fun find(id: Int): T? 21.48 + 21.49 + /** 21.50 + * Inserts an instance into database. 21.51 + * It is not guaranteed that generated fields will be updated in the instance. 21.52 + * 21.53 + * @param instance the instance to insert 21.54 + */ 21.55 + abstract fun save(instance: T) 21.56 + 21.57 + /** 21.58 + * Updates an instance in the database. 21.59 + * 21.60 + * @param instance the instance to update 21.61 + * @return true if an instance has been updated, false if the instance is not present in database 21.62 + */ 21.63 + abstract fun update(instance: T): Boolean 21.64 +} 21.65 \ No newline at end of file
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 22.2 +++ b/src/main/kotlin/de/uapcore/lightpit/dao/AbstractIssueDao.kt Thu Nov 19 13:58:54 2020 +0100 22.3 @@ -0,0 +1,99 @@ 22.4 +/* 22.5 + * Copyright 2020 Mike Becker. All rights reserved. 22.6 + * 22.7 + * Redistribution and use in source and binary forms, with or without 22.8 + * modification, are permitted provided that the following conditions are met: 22.9 + * 22.10 + * 1. Redistributions of source code must retain the above copyright 22.11 + * notice, this list of conditions and the following disclaimer. 22.12 + * 22.13 + * 2. Redistributions in binary form must reproduce the above copyright 22.14 + * notice, this list of conditions and the following disclaimer in the 22.15 + * documentation and/or other materials provided with the distribution. 22.16 + * 22.17 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22.18 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22.19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22.20 + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22.21 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22.22 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22.23 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22.24 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22.25 + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22.26 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22.27 + * 22.28 + */ 22.29 + 22.30 +package de.uapcore.lightpit.dao 22.31 + 22.32 +import de.uapcore.lightpit.entities.* 22.33 +import java.sql.SQLException 22.34 + 22.35 +abstract class AbstractIssueDao : AbstractChildEntityDao<Issue, Project>() { 22.36 + 22.37 + /** 22.38 + * Lists all issues that are related to the specified component and version. 22.39 + * If component or version is null, search for issues that are not assigned to any 22.40 + * component or version, respectively. 22.41 + * 22.42 + * @param project the project 22.43 + * @param component the component 22.44 + * @param version the version 22.45 + * @return a list of issues 22.46 + */ 22.47 + abstract fun list(project: Project, component: Component?, version: Version?): List<Issue> 22.48 + 22.49 + /** 22.50 + * Lists all issues that are related to the specified version. 22.51 + * If the version is null, lists issues that are not assigned to any version. 22.52 + * 22.53 + * @param project the project 22.54 + * @param version the version or null 22.55 + * @return a list of issues 22.56 + */ 22.57 + abstract fun list(project: Project, version: Version?): List<Issue> 22.58 + 22.59 + /** 22.60 + * Lists all issues that are related to the specified component. 22.61 + * If the component is null, lists issues that are not assigned to a component. 22.62 + * 22.63 + * @param project the project 22.64 + * @param component the component or null 22.65 + * @return a list of issues 22.66 + */ 22.67 + abstract fun list(project: Project, component: Component?): List<Issue> 22.68 + 22.69 + /** 22.70 + * Lists all comments for a specific issue in chronological order. 22.71 + * 22.72 + * @param issue the issue 22.73 + * @return the list of comments 22.74 + */ 22.75 + abstract fun listComments(issue: Issue): List<IssueComment> 22.76 + 22.77 + /** 22.78 + * Stores the specified comment in database. 22.79 + * This is an update-or-insert operation. 22.80 + * 22.81 + * @param issue the issue to save the comment for 22.82 + * @param comment the comment to save 22.83 + */ 22.84 + abstract fun saveComment(issue: Issue, comment: IssueComment) 22.85 + 22.86 + /** 22.87 + * Saves an instances to the database. 22.88 + * Implementations of this DAO must guarantee that the generated ID is stored in the instance. 22.89 + * 22.90 + * @param instance the instance to insert 22.91 + * @param parent the parent project 22.92 + * @throws SQLException on any kind of SQL error 22.93 + */ 22.94 + abstract override fun save(instance: Issue, parent: Project) 22.95 + 22.96 + /** 22.97 + * Retrieves the affected, scheduled and resolved versions for the specified issue. 22.98 + * 22.99 + * @param issue the issue to join the information for 22.100 + */ 22.101 + abstract fun joinVersionInformation(issue: Issue) 22.102 +} 22.103 \ No newline at end of file
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 23.2 +++ b/src/main/kotlin/de/uapcore/lightpit/dao/AbstractProjectDao.kt Thu Nov 19 13:58:54 2020 +0100 23.3 @@ -0,0 +1,37 @@ 23.4 +/* 23.5 + * Copyright 2020 Mike Becker. All rights reserved. 23.6 + * 23.7 + * Redistribution and use in source and binary forms, with or without 23.8 + * modification, are permitted provided that the following conditions are met: 23.9 + * 23.10 + * 1. Redistributions of source code must retain the above copyright 23.11 + * notice, this list of conditions and the following disclaimer. 23.12 + * 23.13 + * 2. Redistributions in binary form must reproduce the above copyright 23.14 + * notice, this list of conditions and the following disclaimer in the 23.15 + * documentation and/or other materials provided with the distribution. 23.16 + * 23.17 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23.18 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23.19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23.20 + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23.21 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23.22 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23.23 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23.24 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23.25 + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23.26 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23.27 + * 23.28 + */ 23.29 + 23.30 +package de.uapcore.lightpit.dao 23.31 + 23.32 +import de.uapcore.lightpit.entities.IssueSummary 23.33 +import de.uapcore.lightpit.entities.Project 23.34 + 23.35 +abstract class AbstractProjectDao : AbstractEntityDao<Project>() { 23.36 + 23.37 + abstract fun getIssueSummary(project: Project): IssueSummary 23.38 + 23.39 + abstract fun findByNode(node: String): Project? 23.40 +} 23.41 \ No newline at end of file
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 24.2 +++ b/src/main/kotlin/de/uapcore/lightpit/dao/AbstractUserDao.kt Thu Nov 19 13:58:54 2020 +0100 24.3 @@ -0,0 +1,33 @@ 24.4 +/* 24.5 + * Copyright 2020 Mike Becker. All rights reserved. 24.6 + * 24.7 + * Redistribution and use in source and binary forms, with or without 24.8 + * modification, are permitted provided that the following conditions are met: 24.9 + * 24.10 + * 1. Redistributions of source code must retain the above copyright 24.11 + * notice, this list of conditions and the following disclaimer. 24.12 + * 24.13 + * 2. Redistributions in binary form must reproduce the above copyright 24.14 + * notice, this list of conditions and the following disclaimer in the 24.15 + * documentation and/or other materials provided with the distribution. 24.16 + * 24.17 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24.18 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24.19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24.20 + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24.21 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24.22 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24.23 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24.24 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24.25 + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24.26 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24.27 + * 24.28 + */ 24.29 + 24.30 +package de.uapcore.lightpit.dao 24.31 + 24.32 +import de.uapcore.lightpit.entities.User 24.33 + 24.34 +abstract class AbstractUserDao : AbstractEntityDao<User>() { 24.35 + abstract fun findByUsername(username: String): User? 24.36 +} 24.37 \ No newline at end of file
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 25.2 +++ b/src/main/kotlin/de/uapcore/lightpit/dao/AbstractVersionDao.kt Thu Nov 19 13:58:54 2020 +0100 25.3 @@ -0,0 +1,34 @@ 25.4 +/* 25.5 + * Copyright 2020 Mike Becker. All rights reserved. 25.6 + * 25.7 + * Redistribution and use in source and binary forms, with or without 25.8 + * modification, are permitted provided that the following conditions are met: 25.9 + * 25.10 + * 1. Redistributions of source code must retain the above copyright 25.11 + * notice, this list of conditions and the following disclaimer. 25.12 + * 25.13 + * 2. Redistributions in binary form must reproduce the above copyright 25.14 + * notice, this list of conditions and the following disclaimer in the 25.15 + * documentation and/or other materials provided with the distribution. 25.16 + * 25.17 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 25.18 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25.19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25.20 + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 25.21 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25.22 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25.23 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25.24 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25.25 + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25.26 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25.27 + * 25.28 + */ 25.29 + 25.30 +package de.uapcore.lightpit.dao 25.31 + 25.32 +import de.uapcore.lightpit.entities.Project 25.33 +import de.uapcore.lightpit.entities.Version 25.34 + 25.35 +abstract class AbstractVersionDao : AbstractChildEntityDao<Version, Project>() { 25.36 + abstract fun findByNode(parent: Project, node: String): Version? 25.37 +} 25.38 \ No newline at end of file
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 26.2 +++ b/src/main/kotlin/de/uapcore/lightpit/dao/DaoProvider.kt Thu Nov 19 13:58:54 2020 +0100 26.3 @@ -0,0 +1,35 @@ 26.4 +/* 26.5 + * Copyright 2020 Mike Becker. All rights reserved. 26.6 + * 26.7 + * Redistribution and use in source and binary forms, with or without 26.8 + * modification, are permitted provided that the following conditions are met: 26.9 + * 26.10 + * 1. Redistributions of source code must retain the above copyright 26.11 + * notice, this list of conditions and the following disclaimer. 26.12 + * 26.13 + * 2. Redistributions in binary form must reproduce the above copyright 26.14 + * notice, this list of conditions and the following disclaimer in the 26.15 + * documentation and/or other materials provided with the distribution. 26.16 + * 26.17 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 26.18 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26.19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26.20 + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26.21 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26.22 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26.23 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26.24 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26.25 + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26.26 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26.27 + * 26.28 + */ 26.29 + 26.30 +package de.uapcore.lightpit.dao 26.31 + 26.32 +interface DaoProvider { 26.33 + val userDao: AbstractUserDao 26.34 + val projectDao: AbstractProjectDao 26.35 + val componentDao: AbstractComponentDao 26.36 + val versionDao: AbstractVersionDao 26.37 + val issueDao: AbstractIssueDao 26.38 +} 26.39 \ No newline at end of file
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 27.2 +++ b/src/main/kotlin/de/uapcore/lightpit/dao/postgres/PGComponentDao.kt Thu Nov 19 13:58:54 2020 +0100 27.3 @@ -0,0 +1,110 @@ 27.4 +/* 27.5 + * Copyright 2020 Mike Becker. All rights reserved. 27.6 + * 27.7 + * Redistribution and use in source and binary forms, with or without 27.8 + * modification, are permitted provided that the following conditions are met: 27.9 + * 27.10 + * 1. Redistributions of source code must retain the above copyright 27.11 + * notice, this list of conditions and the following disclaimer. 27.12 + * 27.13 + * 2. Redistributions in binary form must reproduce the above copyright 27.14 + * notice, this list of conditions and the following disclaimer in the 27.15 + * documentation and/or other materials provided with the distribution. 27.16 + * 27.17 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 27.18 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27.19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 27.20 + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 27.21 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27.22 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27.23 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27.24 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27.25 + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27.26 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27.27 + * 27.28 + */ 27.29 + 27.30 +package de.uapcore.lightpit.dao.postgres 27.31 + 27.32 +import de.uapcore.lightpit.dao.AbstractComponentDao 27.33 +import de.uapcore.lightpit.dao.Functions 27.34 +import de.uapcore.lightpit.entities.Component 27.35 +import de.uapcore.lightpit.entities.Project 27.36 +import de.uapcore.lightpit.entities.User 27.37 +import de.uapcore.lightpit.types.WebColor 27.38 +import java.sql.Connection 27.39 +import java.sql.PreparedStatement 27.40 +import java.sql.ResultSet 27.41 + 27.42 +class PGComponentDao(connection: Connection) : AbstractComponentDao() { 27.43 + 27.44 + private val query = "select id, name, node, color, ordinal, description, " + 27.45 + "userid, username, givenname, lastname, mail " + 27.46 + "from lpit_component " + 27.47 + "left join lpit_user on lead = userid" 27.48 + 27.49 + private val listStmt = connection.prepareStatement("$query where project = ? order by ordinal, lower(name)") 27.50 + private val findStmt = connection.prepareStatement("$query where id = ? ") 27.51 + private val findByNodeStmt = connection.prepareStatement("$query where project = ? and node = ?") 27.52 + private val insertStmt = connection.prepareStatement( 27.53 + "insert into lpit_component (name, node, color, ordinal, description, lead, project) values (?, ?, ?, ?, ?, ?, ?)" 27.54 + ) 27.55 + private val updateStmt = connection.prepareStatement( 27.56 + "update lpit_component set name = ?, node = ?, color = ?, ordinal = ?, description = ?, lead = ? where id = ?" 27.57 + ) 27.58 + 27.59 + override fun mapResult(rs: ResultSet): Component { 27.60 + val component = Component(rs.getInt("id")) 27.61 + component.name = rs.getString("name") 27.62 + component.node = rs.getString("node") 27.63 + component.color = try { 27.64 + WebColor(rs.getString("color")) 27.65 + } catch (ex: IllegalArgumentException) { 27.66 + WebColor("000000") 27.67 + } 27.68 + component.ordinal = rs.getInt("ordinal") 27.69 + component.description = rs.getString("description") 27.70 + component.lead = PGUserDao.mapResult(rs).takeUnless { rs.wasNull() } 27.71 + return component 27.72 + } 27.73 + 27.74 + private fun setColumns(stmt: PreparedStatement, instance: Component): Int { 27.75 + var column = 0 27.76 + stmt.setString(++column, instance.name) 27.77 + stmt.setString(++column, instance.node) 27.78 + stmt.setString(++column, instance.color.hex) 27.79 + stmt.setInt(++column, instance.ordinal) 27.80 + Functions.setStringOrNull(stmt, ++column, instance.description) 27.81 + setForeignKeyOrNull(stmt, ++column, instance.lead, User::id) 27.82 + return column 27.83 + } 27.84 + 27.85 + override fun save(instance: Component, parent: Project) { 27.86 + var column = setColumns(insertStmt, instance) 27.87 + insertStmt.setInt(++column, parent.id) 27.88 + insertStmt.executeUpdate() 27.89 + } 27.90 + 27.91 + override fun update(instance: Component): Boolean { 27.92 + var column = setColumns(updateStmt, instance) 27.93 + updateStmt.setInt(++column, instance.id) 27.94 + return updateStmt.executeUpdate() > 0 27.95 + } 27.96 + 27.97 + 27.98 + override fun list(parent: Project): List<Component> { 27.99 + listStmt.setInt(1, parent.id) 27.100 + return super.list(listStmt) 27.101 + } 27.102 + 27.103 + override fun find(id: Int): Component? { 27.104 + findStmt.setInt(1, id) 27.105 + return super.find(findStmt) 27.106 + } 27.107 + 27.108 + override fun findByNode(parent: Project, node: String): Component? { 27.109 + findByNodeStmt.setInt(1, parent.id) 27.110 + findByNodeStmt.setString(2, node) 27.111 + return super.find(findByNodeStmt) 27.112 + } 27.113 +} 27.114 \ No newline at end of file
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 28.2 +++ b/src/main/kotlin/de/uapcore/lightpit/dao/postgres/PGDaoProvider.kt Thu Nov 19 13:58:54 2020 +0100 28.3 @@ -0,0 +1,38 @@ 28.4 +/* 28.5 + * Copyright 2020 Mike Becker. All rights reserved. 28.6 + * 28.7 + * Redistribution and use in source and binary forms, with or without 28.8 + * modification, are permitted provided that the following conditions are met: 28.9 + * 28.10 + * 1. Redistributions of source code must retain the above copyright 28.11 + * notice, this list of conditions and the following disclaimer. 28.12 + * 28.13 + * 2. Redistributions in binary form must reproduce the above copyright 28.14 + * notice, this list of conditions and the following disclaimer in the 28.15 + * documentation and/or other materials provided with the distribution. 28.16 + * 28.17 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 28.18 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28.19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28.20 + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 28.21 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28.22 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28.23 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28.24 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28.25 + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28.26 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28.27 + * 28.28 + */ 28.29 + 28.30 +package de.uapcore.lightpit.dao.postgres 28.31 + 28.32 +import de.uapcore.lightpit.dao.DaoProvider 28.33 +import java.sql.Connection 28.34 + 28.35 +class PGDaoProvider(connection: Connection) : DaoProvider { 28.36 + override val userDao = PGUserDao(connection) 28.37 + override val projectDao = PGProjectDao(connection) 28.38 + override val componentDao = PGComponentDao(connection) 28.39 + override val versionDao = PGVersionDao(connection) 28.40 + override val issueDao = PGIssueDao(connection) 28.41 +} 28.42 \ No newline at end of file
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 29.2 +++ b/src/main/kotlin/de/uapcore/lightpit/dao/postgres/PGIssueDao.kt Thu Nov 19 13:58:54 2020 +0100 29.3 @@ -0,0 +1,249 @@ 29.4 +/* 29.5 + * Copyright 2020 Mike Becker. All rights reserved. 29.6 + * 29.7 + * Redistribution and use in source and binary forms, with or without 29.8 + * modification, are permitted provided that the following conditions are met: 29.9 + * 29.10 + * 1. Redistributions of source code must retain the above copyright 29.11 + * notice, this list of conditions and the following disclaimer. 29.12 + * 29.13 + * 2. Redistributions in binary form must reproduce the above copyright 29.14 + * notice, this list of conditions and the following disclaimer in the 29.15 + * documentation and/or other materials provided with the distribution. 29.16 + * 29.17 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 29.18 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29.19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 29.20 + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 29.21 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29.22 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29.23 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29.24 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29.25 + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29.26 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29.27 + * 29.28 + */ 29.29 + 29.30 +package de.uapcore.lightpit.dao.postgres 29.31 + 29.32 +import de.uapcore.lightpit.dao.AbstractIssueDao 29.33 +import de.uapcore.lightpit.dao.Functions 29.34 +import de.uapcore.lightpit.entities.* 29.35 +import java.sql.Connection 29.36 +import java.sql.PreparedStatement 29.37 +import java.sql.ResultSet 29.38 +import java.sql.Types 29.39 + 29.40 +class PGIssueDao(connection: Connection) : AbstractIssueDao() { 29.41 + 29.42 + private val query = "select issueid, i.project, p.name as projectname, p.node as projectnode, " + 29.43 + "component, c.name as componentname, c.node as componentnode, " + 29.44 + "status, category, subject, i.description, " + 29.45 + "userid, username, givenname, lastname, mail, " + 29.46 + "created, updated, eta " + 29.47 + "from lpit_issue i " + 29.48 + "join lpit_project p on i.project = projectid " + 29.49 + "left join lpit_component c on component = c.id " + 29.50 + "left join lpit_user on userid = assignee " 29.51 + private val list = connection.prepareStatement(query + 29.52 + "where i.project = ? and coalesce(component, -1) = coalesce(?, component, -1)") 29.53 + private val listForVersion = connection.prepareStatement( 29.54 + "with issue_version as ( " + 29.55 + "select issueid, versionid from lpit_issue_affected_version union " + 29.56 + "select issueid, versionid from lpit_issue_resolved_version) " + 29.57 + query + 29.58 + "left join issue_version using (issueid) " + 29.59 + "where i.project = ? " + 29.60 + "and coalesce(versionid,-1) = ? and coalesce(component, -1) = coalesce(?, component, -1)" 29.61 + ) 29.62 + private val find = connection.prepareStatement(query + "where issueid = ? ") 29.63 + private val insert = connection.prepareStatement( 29.64 + "insert into lpit_issue (project, component, status, category, subject, description, assignee, eta) " + 29.65 + "values (?, ?, ?::issue_status, ?::issue_category, ?, ?, ?, ?) returning issueid" 29.66 + ) 29.67 + private val update = connection.prepareStatement( 29.68 + "update lpit_issue set " + 29.69 + "updated = now(), component = ?, status = ?::issue_status, category = ?::issue_category, " + 29.70 + "subject = ?, description = ?, assignee = ?, eta = ? where issueid = ?" 29.71 + ) 29.72 + private val affectedVersions = connection.prepareStatement( 29.73 + "select versionid, name, status, ordinal, node " + 29.74 + "from lpit_version join lpit_issue_affected_version using (versionid) " + 29.75 + "where issueid = ? " + 29.76 + "order by ordinal, name" 29.77 + ) 29.78 + private val clearAffected = connection.prepareStatement("delete from lpit_issue_affected_version where issueid = ?") 29.79 + private val insertAffected = connection.prepareStatement("insert into lpit_issue_affected_version (issueid, versionid) values (?,?)") 29.80 + 29.81 + private val resolvedVersions = connection.prepareStatement( 29.82 + "select versionid, name, status, ordinal, node " + 29.83 + "from lpit_version v join lpit_issue_resolved_version using (versionid) " + 29.84 + "where issueid = ? " + 29.85 + "order by ordinal, name" 29.86 + ) 29.87 + private val clearResolved = connection.prepareStatement("delete from lpit_issue_resolved_version where issueid = ?") 29.88 + private val insertResolved = connection.prepareStatement("insert into lpit_issue_resolved_version (issueid, versionid) values (?,?)") 29.89 + private val insertComment = connection.prepareStatement( 29.90 + "insert into lpit_issue_comment (issueid, comment, userid) values (?, ? ,?)" 29.91 + ) 29.92 + private val updateComment = connection.prepareStatement( 29.93 + "update lpit_issue_comment set comment = ?, updated = now(), updatecount = updatecount+1 where commentid = ?" 29.94 + ) 29.95 + private val listComments = connection.prepareStatement( 29.96 + "select * from lpit_issue_comment left join lpit_user using (userid) where issueid = ? order by created" 29.97 + ) 29.98 + 29.99 + override fun mapResult(rs: ResultSet): Issue { 29.100 + val project = Project(rs.getInt("project")) 29.101 + project.name = rs.getString("projectname") 29.102 + project.node = rs.getString("projectnode") 29.103 + val issue = Issue(rs.getInt("issueid")) 29.104 + issue.project = project 29.105 + issue.component = rs.getInt("component").let { id -> 29.106 + if (rs.wasNull()) { 29.107 + null 29.108 + } else { 29.109 + val component = Component(id) 29.110 + component.name = rs.getString("componentname") 29.111 + component.node = rs.getString("componentnode") 29.112 + component 29.113 + } 29.114 + } 29.115 + issue.status = IssueStatus.valueOf(rs.getString("status")) 29.116 + issue.category = IssueCategory.valueOf(rs.getString("category")) 29.117 + issue.subject = rs.getString("subject") 29.118 + issue.description = rs.getString("description") 29.119 + issue.assignee = PGUserDao.mapResult(rs).takeUnless { rs.wasNull() } 29.120 + issue.created = rs.getTimestamp("created") 29.121 + issue.updated = rs.getTimestamp("updated") 29.122 + issue.eta = rs.getDate("eta") 29.123 + return issue 29.124 + } 29.125 + 29.126 + private fun updateVersionLists(instance: Issue) { 29.127 + clearAffected.setInt(1, instance.id) 29.128 + clearResolved.setInt(1, instance.id) 29.129 + insertAffected.setInt(1, instance.id) 29.130 + insertResolved.setInt(1, instance.id) 29.131 + clearAffected.executeUpdate() 29.132 + clearResolved.executeUpdate() 29.133 + for (v: Version in instance.affectedVersions) { 29.134 + insertAffected.setInt(2, v.id) 29.135 + insertAffected.executeUpdate() 29.136 + } 29.137 + for (v: Version in instance.resolvedVersions) { 29.138 + insertResolved.setInt(2, v.id) 29.139 + insertResolved.executeUpdate() 29.140 + } 29.141 + } 29.142 + 29.143 + private fun setData(stmt: PreparedStatement, column: Int, instance: Issue): Int { 29.144 + var col = column 29.145 + setForeignKeyOrNull(stmt, ++col, instance.component, Component::id) 29.146 + stmt.setString(++col, instance.status.name) 29.147 + stmt.setString(++col, instance.category.name) 29.148 + stmt.setString(++col, instance.subject) 29.149 + Functions.setStringOrNull(stmt, ++col, instance.description) 29.150 + setForeignKeyOrNull(stmt, ++col, instance.assignee, User::id) 29.151 + Functions.setDateOrNull(stmt, ++col, instance.eta) 29.152 + return col 29.153 + } 29.154 + 29.155 + override fun save(instance: Issue, parent: Project) { 29.156 + instance.project = parent 29.157 + var column = 0 29.158 + insert.setInt(++column, parent.id) 29.159 + setData(insert, column, instance) 29.160 + // insert and retrieve the ID 29.161 + val rs = insert.executeQuery() 29.162 + rs.next() 29.163 + instance.id = rs.getInt(1) 29.164 + updateVersionLists(instance) 29.165 + } 29.166 + 29.167 + override fun update(instance: Issue): Boolean { 29.168 + var column = setData(update, 0, instance) 29.169 + update.setInt(++column, instance.id) 29.170 + return if (update.executeUpdate() > 0) { 29.171 + updateVersionLists(instance) 29.172 + true 29.173 + } else { 29.174 + false 29.175 + } 29.176 + } 29.177 + 29.178 + override fun list(parent: Project): List<Issue> { 29.179 + list.setInt(1, parent.id) 29.180 + list.setNull(2, Types.INTEGER) 29.181 + return super.list(list) 29.182 + } 29.183 + 29.184 + override fun list(project: Project, component: Component?, version: Version?): List<Issue> { 29.185 + listForVersion.setInt(1, project.id) 29.186 + listForVersion.setInt(2, version?.id ?: -1) 29.187 + listForVersion.setInt(3, component?.id ?: -1) 29.188 + return super.list(listForVersion) 29.189 + } 29.190 + 29.191 + override fun list(project: Project, version: Version?): List<Issue> { 29.192 + listForVersion.setInt(1, project.id) 29.193 + listForVersion.setInt(2, version?.id ?: -1) 29.194 + listForVersion.setNull(3, Types.INTEGER) 29.195 + return super.list(listForVersion) 29.196 + } 29.197 + 29.198 + override fun list(project: Project, component: Component?): List<Issue> { 29.199 + list.setInt(1, project.id) 29.200 + list.setInt(2, component?.id ?: -1) 29.201 + return super.list(list) 29.202 + } 29.203 + 29.204 + override fun find(id: Int): Issue? { 29.205 + find.setInt(1, id) 29.206 + return super.find(find) 29.207 + } 29.208 + 29.209 + private fun listVersions(stmt: PreparedStatement, issue: Issue): List<Version> { 29.210 + stmt.setInt(1, issue.id) 29.211 + return sequence { 29.212 + stmt.executeQuery().use { result -> 29.213 + while (result.next()) yield(PGVersionDao.mapResult(result)) 29.214 + } 29.215 + }.toList() 29.216 + } 29.217 + 29.218 + override fun joinVersionInformation(issue: Issue) { 29.219 + issue.affectedVersions = listVersions(affectedVersions, issue) 29.220 + issue.resolvedVersions = listVersions(resolvedVersions, issue) 29.221 + } 29.222 + 29.223 + override fun listComments(issue: Issue): List<IssueComment> { 29.224 + listComments.setInt(1, issue.id) 29.225 + return sequence { 29.226 + listComments.executeQuery().use { rs -> 29.227 + while (rs.next()) { 29.228 + val comment = IssueComment(rs.getInt("commentid")) 29.229 + comment.created = rs.getTimestamp("created") 29.230 + comment.updated = rs.getTimestamp("updated") 29.231 + comment.updateCount = rs.getInt("updatecount") 29.232 + comment.comment = rs.getString("comment") 29.233 + comment.author = PGUserDao.mapResult(rs).takeUnless { rs.wasNull() } 29.234 + yield(comment) 29.235 + } 29.236 + } 29.237 + }.toList() 29.238 + } 29.239 + 29.240 + override fun saveComment(issue: Issue, comment: IssueComment) { 29.241 + if (comment.id >= 0) { 29.242 + updateComment.setString(1, comment.comment) 29.243 + updateComment.setInt(2, comment.id) 29.244 + updateComment.execute() 29.245 + } else { 29.246 + insertComment.setInt(1, issue.id) 29.247 + insertComment.setString(2, comment.comment) 29.248 + setForeignKeyOrNull(insertComment, 3, comment.author, User::id) 29.249 + insertComment.execute() 29.250 + } 29.251 + } 29.252 +} 29.253 \ No newline at end of file
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 30.2 +++ b/src/main/kotlin/de/uapcore/lightpit/dao/postgres/PGProjectDao.kt Thu Nov 19 13:58:54 2020 +0100 30.3 @@ -0,0 +1,122 @@ 30.4 +/* 30.5 + * Copyright 2020 Mike Becker. All rights reserved. 30.6 + * 30.7 + * Redistribution and use in source and binary forms, with or without 30.8 + * modification, are permitted provided that the following conditions are met: 30.9 + * 30.10 + * 1. Redistributions of source code must retain the above copyright 30.11 + * notice, this list of conditions and the following disclaimer. 30.12 + * 30.13 + * 2. Redistributions in binary form must reproduce the above copyright 30.14 + * notice, this list of conditions and the following disclaimer in the 30.15 + * documentation and/or other materials provided with the distribution. 30.16 + * 30.17 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 30.18 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30.19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 30.20 + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 30.21 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30.22 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 30.23 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30.24 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30.25 + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30.26 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30.27 + * 30.28 + */ 30.29 + 30.30 +package de.uapcore.lightpit.dao.postgres 30.31 + 30.32 +import de.uapcore.lightpit.dao.AbstractProjectDao 30.33 +import de.uapcore.lightpit.dao.Functions 30.34 +import de.uapcore.lightpit.entities.IssueSummary 30.35 +import de.uapcore.lightpit.entities.Project 30.36 +import de.uapcore.lightpit.entities.User 30.37 +import java.sql.Connection 30.38 +import java.sql.PreparedStatement 30.39 +import java.sql.ResultSet 30.40 + 30.41 +class PGProjectDao(connection: Connection) : AbstractProjectDao() { 30.42 + 30.43 + private val query = "select projectid, name, node, description, repourl, " + 30.44 + "userid, username, lastname, givenname, mail " + 30.45 + "from lpit_project " + 30.46 + "left join lpit_user owner on lpit_project.owner = owner.userid " 30.47 + 30.48 + private val listStmt = connection.prepareStatement("$query order by name") 30.49 + private val findStmt = connection.prepareStatement("$query where projectid = ?") 30.50 + private val findByNodeStmt = connection.prepareStatement("$query where node = ?") 30.51 + private val issueSummaryStmt = connection.prepareStatement( 30.52 + "select phase, count(*) as total " + 30.53 + "from lpit_issue " + 30.54 + "join lpit_issue_phases using(status) " + 30.55 + "where project = ? " + 30.56 + "group by phase " 30.57 + ) 30.58 + private val insertStmt = connection.prepareStatement( 30.59 + "insert into lpit_project (name, node, description, repourl, owner) values (?, ?, ?, ?, ?)" 30.60 + ) 30.61 + private val updateStmt = connection.prepareStatement( 30.62 + "update lpit_project set name = ?, node = ?, description = ?, repourl = ?, owner = ? where projectid = ?" 30.63 + ) 30.64 + 30.65 + override fun mapResult(rs: ResultSet): Project { 30.66 + val proj = Project(rs.getInt("projectid")) 30.67 + proj.name = rs.getString("name") 30.68 + proj.node = rs.getString("node") 30.69 + proj.description = rs.getString("description") 30.70 + proj.repoUrl = rs.getString("repourl") 30.71 + proj.owner = PGUserDao.mapResult(rs).takeUnless { rs.wasNull() } 30.72 + return proj 30.73 + } 30.74 + 30.75 + override fun getIssueSummary(project: Project): IssueSummary { 30.76 + issueSummaryStmt.setInt(1, project.id) 30.77 + val result = issueSummaryStmt.executeQuery() 30.78 + val summary = IssueSummary() 30.79 + while (result.next()) { 30.80 + val phase = result.getInt("phase") 30.81 + val total = result.getInt("total") 30.82 + when (phase) { 30.83 + 0 -> summary.open = total 30.84 + 1 -> summary.active = total 30.85 + 2 -> summary.done = total 30.86 + } 30.87 + } 30.88 + return summary 30.89 + } 30.90 + 30.91 + private fun setColumns(stmt: PreparedStatement, instance: Project): Int { 30.92 + var column = 0 30.93 + stmt.setString(++column, instance.name) 30.94 + stmt.setString(++column, instance.node) 30.95 + Functions.setStringOrNull(stmt, ++column, instance.description) 30.96 + Functions.setStringOrNull(stmt, ++column, instance.repoUrl) 30.97 + setForeignKeyOrNull(stmt, ++column, instance.owner, User::id) 30.98 + return column 30.99 + } 30.100 + 30.101 + override fun save(instance: Project) { 30.102 + setColumns(insertStmt, instance) 30.103 + insertStmt.executeUpdate() 30.104 + } 30.105 + 30.106 + override fun update(instance: Project): Boolean { 30.107 + var column = setColumns(updateStmt, instance) 30.108 + updateStmt.setInt(++column, instance.id) 30.109 + return updateStmt.executeUpdate() > 0 30.110 + } 30.111 + 30.112 + override fun list(): List<Project> { 30.113 + return super.list(listStmt) 30.114 + } 30.115 + 30.116 + override fun find(id: Int): Project? { 30.117 + findStmt.setInt(1, id) 30.118 + return super.find(findStmt) 30.119 + } 30.120 + 30.121 + override fun findByNode(node: String): Project? { 30.122 + findByNodeStmt.setString(1, node) 30.123 + return super.find(findByNodeStmt) 30.124 + } 30.125 +} 30.126 \ No newline at end of file
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 31.2 +++ b/src/main/kotlin/de/uapcore/lightpit/dao/postgres/PGUserDao.kt Thu Nov 19 13:58:54 2020 +0100 31.3 @@ -0,0 +1,95 @@ 31.4 +/* 31.5 + * Copyright 2020 Mike Becker. All rights reserved. 31.6 + * 31.7 + * Redistribution and use in source and binary forms, with or without 31.8 + * modification, are permitted provided that the following conditions are met: 31.9 + * 31.10 + * 1. Redistributions of source code must retain the above copyright 31.11 + * notice, this list of conditions and the following disclaimer. 31.12 + * 31.13 + * 2. Redistributions in binary form must reproduce the above copyright 31.14 + * notice, this list of conditions and the following disclaimer in the 31.15 + * documentation and/or other materials provided with the distribution. 31.16 + * 31.17 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 31.18 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 31.19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 31.20 + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 31.21 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31.22 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31.23 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31.24 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31.25 + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31.26 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31.27 + * 31.28 + */ 31.29 + 31.30 +package de.uapcore.lightpit.dao.postgres 31.31 + 31.32 +import de.uapcore.lightpit.dao.AbstractUserDao 31.33 +import de.uapcore.lightpit.dao.Functions 31.34 +import de.uapcore.lightpit.entities.User 31.35 +import java.sql.Connection 31.36 +import java.sql.ResultSet 31.37 + 31.38 +class PGUserDao(connection: Connection) : AbstractUserDao() { 31.39 + 31.40 + companion object { 31.41 + fun mapResult(rs: ResultSet): User { 31.42 + val id = rs.getInt("userid") 31.43 + return if (rs.wasNull()) { 31.44 + User(-1) 31.45 + } else { 31.46 + val user = User(id) 31.47 + user.username = rs.getString("username") 31.48 + user.givenname = Functions.getSafeString(rs, "givenname") 31.49 + user.lastname = Functions.getSafeString(rs, "lastname") 31.50 + user.mail = Functions.getSafeString(rs, "mail") 31.51 + user 31.52 + } 31.53 + } 31.54 + } 31.55 + 31.56 + private val listStmt = connection.prepareStatement( 31.57 + "select userid, username, lastname, givenname, mail " + 31.58 + "from lpit_user where userid >= 0 " + 31.59 + "order by username") 31.60 + private val findStmt = connection.prepareStatement( 31.61 + "select userid, username, lastname, givenname, mail " + 31.62 + "from lpit_user where userid = ? ") 31.63 + private val findByUsernameStmt = connection.prepareStatement( 31.64 + "select userid, username, lastname, givenname, mail " + 31.65 + "from lpit_user where lower(username) = lower(?) ") 31.66 + private val insertStmt = connection.prepareStatement("insert into lpit_user (username, lastname, givenname, mail) values (?, ?, ?, ?)") 31.67 + private val updateStmt = connection.prepareStatement("update lpit_user set lastname = ?, givenname = ?, mail = ? where userid = ?") 31.68 + 31.69 + override fun mapResult(rs: ResultSet): User = Companion.mapResult(rs) 31.70 + 31.71 + override fun save(instance: User) { 31.72 + insertStmt.setString(1, instance.username) 31.73 + Functions.setStringOrNull(insertStmt, 2, instance.lastname) 31.74 + Functions.setStringOrNull(insertStmt, 3, instance.givenname) 31.75 + Functions.setStringOrNull(insertStmt, 4, instance.mail) 31.76 + insertStmt.executeUpdate() 31.77 + } 31.78 + 31.79 + override fun update(instance: User): Boolean { 31.80 + Functions.setStringOrNull(updateStmt, 1, instance.lastname) 31.81 + Functions.setStringOrNull(updateStmt, 2, instance.givenname) 31.82 + Functions.setStringOrNull(updateStmt, 3, instance.mail) 31.83 + updateStmt.setInt(4, instance.id) 31.84 + return updateStmt.executeUpdate() > 0 31.85 + } 31.86 + 31.87 + override fun list(): List<User> = super.list(listStmt) 31.88 + 31.89 + override fun find(id: Int): User? { 31.90 + findStmt.setInt(1, id) 31.91 + return super.find(findStmt) 31.92 + } 31.93 + 31.94 + override fun findByUsername(username: String): User? { 31.95 + findByUsernameStmt.setString(1, username) 31.96 + return super.find(findByUsernameStmt) 31.97 + } 31.98 +} 31.99 \ No newline at end of file
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 32.2 +++ b/src/main/kotlin/de/uapcore/lightpit/dao/postgres/PGVersionDao.kt Thu Nov 19 13:58:54 2020 +0100 32.3 @@ -0,0 +1,105 @@ 32.4 +/* 32.5 + * Copyright 2020 Mike Becker. All rights reserved. 32.6 + * 32.7 + * Redistribution and use in source and binary forms, with or without 32.8 + * modification, are permitted provided that the following conditions are met: 32.9 + * 32.10 + * 1. Redistributions of source code must retain the above copyright 32.11 + * notice, this list of conditions and the following disclaimer. 32.12 + * 32.13 + * 2. Redistributions in binary form must reproduce the above copyright 32.14 + * notice, this list of conditions and the following disclaimer in the 32.15 + * documentation and/or other materials provided with the distribution. 32.16 + * 32.17 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 32.18 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 32.19 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 32.20 + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 32.21 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32.22 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 32.23 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32.24 + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 32.25 + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32.26 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32.27 + * 32.28 + */ 32.29 + 32.30 +package de.uapcore.lightpit.dao.postgres 32.31 + 32.32 +import de.uapcore.lightpit.dao.AbstractVersionDao 32.33 +import de.uapcore.lightpit.entities.Project 32.34 +import de.uapcore.lightpit.entities.Version 32.35 +import de.uapcore.lightpit.entities.VersionStatus 32.36 +import java.sql.Connection 32.37 +import java.sql.PreparedStatement 32.38 +import java.sql.ResultSet 32.39 + 32.40 +class PGVersionDao(connection: Connection) : AbstractVersionDao() { 32.41 + 32.42 + companion object { 32.43 + fun mapResult(rs: ResultSet): Version { 32.44 + val id = rs.getInt("versionid") 32.45 + return if (rs.wasNull()) { 32.46 + Version(-1) 32.47 + } else { 32.48 + val version = Version(id) 32.49 + version.name = rs.getString("name") 32.50 + version.node = rs.getString("node") 32.51 + version.ordinal = rs.getInt("ordinal") 32.52 + version.status = VersionStatus.valueOf(rs.getString("status")) 32.53 + version 32.54 + } 32.55 + } 32.56 + } 32.57 + 32.58 + private val query = "select versionid, project, name, node, ordinal, status from lpit_version" 32.59 + private val listStmt = connection.prepareStatement(query + " where project = ? " + 32.60 + "order by ordinal desc, lower(name) desc") 32.61 + private val findStmt = connection.prepareStatement("$query where versionid = ?") 32.62 + private val findByNodeStmt = connection.prepareStatement("$query where project = ? and node = ?") 32.63 + private val insertStmt = connection.prepareStatement( 32.64 + "insert into lpit_version (name, node, ordinal, status, project) values (?, ?, ?, ?::version_status, ?)" 32.65 + ) 32.66 + private val updateStmt = connection.prepareStatement( 32.67 + "update lpit_version set name = ?, node = ?, ordinal = ?, status = ?::version_status where versionid = ?" 32.68 + ) 32.69 + 32.70 + override fun mapResult(rs: ResultSet): Version = Companion.mapResult(rs) 32.71 + 32.72 + private fun setFields(stmt: PreparedStatement, instance: Version): Int { 32.73 + var column = 0 32.74 + stmt.setString(++column, instance.name) 32.75 + stmt.setString(++column, instance.node) 32.76 + stmt.setInt(++column, instance.ordinal) 32.77 + stmt.setString(++column, instance.status.name) 32.78 + return column 32.79 + } 32.80 + 32.81 + override fun save(instance: Version, parent: Project) { 32.82 + var column = setFields(insertStmt, instance) 32.83 + insertStmt.setInt(++column, parent.id) 32.84 + insertStmt.executeUpdate() 32.85 + } 32.86 + 32.87 + override fun update(instance: Version): Boolean { 32.88 + var column = setFields(updateStmt, instance) 32.89 + updateStmt.setInt(++column, instance.id) 32.90 + return updateStmt.executeUpdate() > 0 32.91 + } 32.92 + 32.93 + override fun list(parent: Project): List<Version> { 32.94 + listStmt.setInt(1, parent.id) 32.95 + return super.list(listStmt) 32.96 + } 32.97 + 32.98 + override fun find(id: Int): Version? { 32.99 + findStmt.setInt(1, id) 32.100 + return super.find(findStmt) 32.101 + } 32.102 + 32.103 + override fun findByNode(parent: Project, node: String): Version? { 32.104 + findByNodeStmt.setInt(1, parent.id) 32.105 + findByNodeStmt.setString(2, node) 32.106 + return super.find(findByNodeStmt) 32.107 + } 32.108 +} 32.109 \ No newline at end of file
33.1 --- a/src/main/kotlin/de/uapcore/lightpit/entities/User.kt Fri Nov 06 10:50:32 2020 +0100 33.2 +++ b/src/main/kotlin/de/uapcore/lightpit/entities/User.kt Thu Nov 19 13:58:54 2020 +0100 33.3 @@ -26,7 +26,7 @@ 33.4 package de.uapcore.lightpit.entities 33.5 33.6 data class User(val id: Int) { 33.7 - var username = "anonymous" 33.8 + var username = "" 33.9 var mail = "" 33.10 var givenname = "" 33.11 var lastname = ""