24 */ |
24 */ |
25 |
25 |
26 package de.uapcore.lightpit.dao |
26 package de.uapcore.lightpit.dao |
27 |
27 |
28 import de.uapcore.lightpit.entities.* |
28 import de.uapcore.lightpit.entities.* |
29 import de.uapcore.lightpit.filter.* |
|
30 import de.uapcore.lightpit.types.WebColor |
29 import de.uapcore.lightpit.types.WebColor |
|
30 import de.uapcore.lightpit.util.* |
|
31 import de.uapcore.lightpit.viewmodel.ComponentSummary |
|
32 import de.uapcore.lightpit.viewmodel.IssueSummary |
|
33 import de.uapcore.lightpit.viewmodel.VersionSummary |
31 import java.sql.Connection |
34 import java.sql.Connection |
32 import java.sql.PreparedStatement |
35 import java.sql.PreparedStatement |
33 import java.sql.ResultSet |
36 import java.sql.ResultSet |
34 |
37 |
35 class PostgresDataAccessObject(private val connection: Connection) : DataAccessObject { |
38 class PostgresDataAccessObject(private val connection: Connection) : DataAccessObject { |
127 stmtUpdateUser.execute() |
130 stmtUpdateUser.execute() |
128 } |
131 } |
129 //</editor-fold> |
132 //</editor-fold> |
130 |
133 |
131 //<editor-fold desc="Version"> |
134 //<editor-fold desc="Version"> |
|
135 |
|
136 private fun obtainVersion(rs: ResultSet) = |
|
137 Version(rs.getInt("versionid"), rs.getInt("project")).apply { |
|
138 name = rs.getString("name") |
|
139 node = rs.getString("node") |
|
140 ordinal = rs.getInt("ordinal") |
|
141 status = rs.getEnum("status") |
|
142 } |
|
143 |
132 private fun selectVersions(stmt: PreparedStatement) = sequence { |
144 private fun selectVersions(stmt: PreparedStatement) = sequence { |
133 stmt.executeQuery().use { rs -> |
145 stmt.executeQuery().use { rs -> |
134 while (rs.next()) { |
146 while (rs.next()) { |
135 yield(Version(rs.getInt("versionid"), rs.getInt("project")).apply { |
147 yield(obtainVersion(rs)) |
136 name = rs.getString("name") |
|
137 node = rs.getString("node") |
|
138 ordinal = rs.getInt("ordinal") |
|
139 status = rs.getEnum("status") |
|
140 }) |
|
141 } |
148 } |
142 } |
149 } |
143 } |
150 } |
144 |
151 |
145 private fun setVersionFields(stmt: PreparedStatement, obj: Version): Int { |
152 private fun setVersionFields(stmt: PreparedStatement, obj: Version): Int { |
161 where project = ? |
168 where project = ? |
162 order by ordinal desc, lower(name) desc |
169 order by ordinal desc, lower(name) desc |
163 """ |
170 """ |
164 ) |
171 ) |
165 } |
172 } |
|
173 private val stmtVersionSummaries by lazy { |
|
174 connection.prepareStatement( |
|
175 """ |
|
176 with version_map(issueid, versionid, isresolved) as ( |
|
177 select issueid, versionid, 1 |
|
178 from lpit_issue_resolved_version |
|
179 union |
|
180 select issueid, versionid, 0 |
|
181 from lpit_issue_affected_version |
|
182 ), |
|
183 issues as ( |
|
184 select versionid, phase, isresolved, count(issueid) as total |
|
185 from lpit_issue |
|
186 join version_map using (issueid) |
|
187 join lpit_issue_phases using (status) |
|
188 group by versionid, phase, isresolved |
|
189 ), |
|
190 summary as ( |
|
191 select versionid, phase, isresolved, total |
|
192 from lpit_version v |
|
193 left join issues using (versionid) |
|
194 where v.project = ? |
|
195 ) |
|
196 select versionid, project, name, node, ordinal, status, phase, isresolved, total |
|
197 from lpit_version |
|
198 join summary using (versionid) |
|
199 order by ordinal, name |
|
200 """ |
|
201 ) |
|
202 } |
166 private val stmtVersionByID by lazy { |
203 private val stmtVersionByID by lazy { |
167 connection.prepareStatement( |
204 connection.prepareStatement( |
168 """${versionQuery} |
205 """${versionQuery} |
169 where versionid = ? |
206 where versionid = ? |
170 """ |
207 """ |
195 } |
232 } |
196 |
233 |
197 override fun listVersions(project: Project): List<Version> { |
234 override fun listVersions(project: Project): List<Version> { |
198 stmtVersions.setInt(1, project.id) |
235 stmtVersions.setInt(1, project.id) |
199 return selectVersions(stmtVersions).toList() |
236 return selectVersions(stmtVersions).toList() |
|
237 } |
|
238 |
|
239 override fun listVersionSummaries(project: Project): List<VersionSummary> { |
|
240 stmtVersionSummaries.setInt(1, project.id) |
|
241 return sequence { |
|
242 stmtVersionSummaries.executeQuery().use { rs -> |
|
243 while (rs.next()) { |
|
244 val versionSummary = VersionSummary(obtainVersion(rs)) |
|
245 val phase = rs.getInt("phase") |
|
246 val total = rs.getInt("total") |
|
247 val issueSummary = |
|
248 if (rs.getBoolean("isresolved")) versionSummary.resolvedTotal else versionSummary.reportedTotal |
|
249 when (phase) { |
|
250 0 -> issueSummary.open = total |
|
251 1 -> issueSummary.active = total |
|
252 2 -> issueSummary.done = total |
|
253 } |
|
254 yield(versionSummary) |
|
255 } |
|
256 } |
|
257 }.toList() |
200 } |
258 } |
201 |
259 |
202 override fun findVersion(id: Int): Version? { |
260 override fun findVersion(id: Int): Version? { |
203 stmtVersionByID.setInt(1, id) |
261 stmtVersionByID.setInt(1, id) |
204 return selectVersions(stmtVersionByID).firstOrNull() |
262 return selectVersions(stmtVersionByID).firstOrNull() |
222 stmtUpdateVersion.execute() |
280 stmtUpdateVersion.execute() |
223 } |
281 } |
224 //</editor-fold> |
282 //</editor-fold> |
225 |
283 |
226 //<editor-fold desc="Component"> |
284 //<editor-fold desc="Component"> |
|
285 |
|
286 private fun obtainComponent(rs: ResultSet): Component = |
|
287 Component(rs.getInt("id"), rs.getInt("project")).apply { |
|
288 name = rs.getString("name") |
|
289 node = rs.getString("node") |
|
290 color = try { |
|
291 WebColor(rs.getString("color")) |
|
292 } catch (ex: IllegalArgumentException) { |
|
293 WebColor("000000") |
|
294 } |
|
295 ordinal = rs.getInt("ordinal") |
|
296 description = rs.getString("description") |
|
297 lead = selectUserInfo(rs) |
|
298 } |
|
299 |
227 private fun selectComponents(stmt: PreparedStatement) = sequence { |
300 private fun selectComponents(stmt: PreparedStatement) = sequence { |
228 stmt.executeQuery().use { rs -> |
301 stmt.executeQuery().use { rs -> |
229 while (rs.next()) { |
302 while (rs.next()) { |
230 yield(Component(rs.getInt("id"), rs.getInt("project")).apply { |
303 yield(obtainComponent(rs)) |
231 name = rs.getString("name") |
|
232 node = rs.getString("node") |
|
233 color = try { |
|
234 WebColor(rs.getString("color")) |
|
235 } catch (ex: IllegalArgumentException) { |
|
236 WebColor("000000") |
|
237 } |
|
238 ordinal = rs.getInt("ordinal") |
|
239 description = rs.getString("description") |
|
240 lead = selectUserInfo(rs) |
|
241 }) |
|
242 } |
304 } |
243 } |
305 } |
244 } |
306 } |
245 |
307 |
246 private fun setComponentFields(stmt: PreparedStatement, obj: Component): Int { |
308 private fun setComponentFields(stmt: PreparedStatement, obj: Component): Int { |
270 where project = ? |
332 where project = ? |
271 order by ordinal, lower(name) |
333 order by ordinal, lower(name) |
272 """ |
334 """ |
273 ) |
335 ) |
274 } |
336 } |
|
337 private val stmtComponentSummaries by lazy { |
|
338 connection.prepareStatement( |
|
339 """ |
|
340 with issues as ( |
|
341 select component, phase, count(issueid) as total |
|
342 from lpit_issue |
|
343 join lpit_issue_phases using (status) |
|
344 group by component, phase |
|
345 ), |
|
346 summary as ( |
|
347 select c.id, phase, total |
|
348 from lpit_component c |
|
349 left join issues i on c.id = i.component |
|
350 where c.project = ? |
|
351 ) |
|
352 select c.id, project, name, node, color, ordinal, description, |
|
353 userid, username, givenname, lastname, mail, phase, total |
|
354 from lpit_component c |
|
355 left join lpit_user on lead = userid |
|
356 join summary s on c.id = s.id |
|
357 order by ordinal, name |
|
358 """ |
|
359 ) |
|
360 } |
275 private val stmtComponentById by lazy { |
361 private val stmtComponentById by lazy { |
276 connection.prepareStatement( |
362 connection.prepareStatement( |
277 """${componentQuery} |
363 """${componentQuery} |
278 where id = ? |
364 where id = ? |
279 """ |
365 """ |
301 } |
387 } |
302 |
388 |
303 override fun listComponents(project: Project): List<Component> { |
389 override fun listComponents(project: Project): List<Component> { |
304 stmtComponents.setInt(1, project.id) |
390 stmtComponents.setInt(1, project.id) |
305 return selectComponents(stmtComponents).toList() |
391 return selectComponents(stmtComponents).toList() |
|
392 } |
|
393 |
|
394 override fun listComponentSummaries(project: Project): List<ComponentSummary> { |
|
395 stmtComponentSummaries.setInt(1, project.id) |
|
396 return sequence { |
|
397 stmtComponentSummaries.executeQuery().use { rs -> |
|
398 while (rs.next()) { |
|
399 val componentSummary = ComponentSummary(obtainComponent(rs)) |
|
400 val phase = rs.getInt("phase") |
|
401 val total = rs.getInt("total") |
|
402 when (phase) { |
|
403 0 -> componentSummary.issueSummary.open = total |
|
404 1 -> componentSummary.issueSummary.active = total |
|
405 2 -> componentSummary.issueSummary.done = total |
|
406 } |
|
407 yield(componentSummary) |
|
408 } |
|
409 } |
|
410 }.toList() |
306 } |
411 } |
307 |
412 |
308 override fun findComponent(id: Int): Component? { |
413 override fun findComponent(id: Int): Component? { |
309 stmtComponentById.setInt(1, id) |
414 stmtComponentById.setInt(1, id) |
310 return selectComponents(stmtComponentById).firstOrNull() |
415 return selectComponents(stmtComponentById).firstOrNull() |
469 Component(it, proj.id).apply { |
574 Component(it, proj.id).apply { |
470 name = rs.getString("componentname") |
575 name = rs.getString("componentname") |
471 node = rs.getString("componentnode") |
576 node = rs.getString("componentnode") |
472 } |
577 } |
473 } |
578 } |
474 val issue = Issue(rs.getInt("issueid"), proj, comp).apply { |
579 val issue = Issue(rs.getInt("issueid"), proj).apply { |
475 component = comp |
580 component = comp |
476 status = rs.getEnum("status") |
581 status = rs.getEnum("status") |
477 category = rs.getEnum("category") |
582 category = rs.getEnum("category") |
478 subject = rs.getString("subject") |
583 subject = rs.getString("subject") |
479 description = rs.getString("description") |
584 description = rs.getString("description") |
670 stmtInsertResolvedVersion.setInt(2, it.id) |
775 stmtInsertResolvedVersion.setInt(2, it.id) |
671 stmtInsertResolvedVersion.execute() |
776 stmtInsertResolvedVersion.execute() |
672 } |
777 } |
673 } |
778 } |
674 |
779 |
675 override fun insertIssue(issue: Issue) { |
780 override fun insertIssue(issue: Issue): Int { |
676 val col = setIssueFields(stmtInsertIssue, issue) |
781 val col = setIssueFields(stmtInsertIssue, issue) |
677 stmtInsertIssue.setInt(col, issue.project.id) |
782 stmtInsertIssue.setInt(col, issue.project.id) |
678 stmtInsertIssue.executeQuery().use { rs -> |
783 val id = stmtInsertIssue.executeQuery().use { rs -> |
679 rs.next() |
784 rs.next() |
680 issue.id = rs.getInt(1) |
785 rs.getInt(1) |
681 } |
786 } |
682 insertVersionInfo(issue) |
787 insertVersionInfo(issue) |
|
788 return id |
683 } |
789 } |
684 |
790 |
685 override fun updateIssue(issue: Issue) { |
791 override fun updateIssue(issue: Issue) { |
686 val col = setIssueFields(stmtUpdateIssue, issue) |
792 val col = setIssueFields(stmtUpdateIssue, issue) |
687 stmtUpdateIssue.setInt(col, issue.id) |
793 stmtUpdateIssue.setInt(col, issue.id) |