PageRenderTime 53ms CodeModel.GetById 7ms RepoModel.GetById 1ms app.codeStats 0ms

/components/server-data-access/src/main/java/org/marvelution/jji/data/access/DefaultBuildDAO.java

https://bitbucket.org/marvelution/jira-jenkins-integration
Java | 274 lines | 232 code | 26 blank | 16 comment | 12 complexity | a2baa367ecb586aa728790082d3a9128 MD5 | raw file
  1. /*
  2. * Copyright (c) 2012-present Marvelution Holding B.V.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.marvelution.jji.data.access;
  17. import java.time.*;
  18. import java.util.*;
  19. import javax.annotation.*;
  20. import javax.inject.*;
  21. import org.marvelution.jji.data.access.api.*;
  22. import org.marvelution.jji.data.access.model.*;
  23. import org.marvelution.jji.data.access.querydsl.*;
  24. import org.marvelution.jji.data.services.api.*;
  25. import org.marvelution.jji.model.*;
  26. import com.atlassian.pocketknife.api.querydsl.*;
  27. import com.atlassian.pocketknife.api.querydsl.stream.*;
  28. import com.atlassian.pocketknife.api.querydsl.util.*;
  29. import com.querydsl.core.types.*;
  30. import com.querydsl.core.types.dsl.*;
  31. import com.querydsl.sql.*;
  32. import com.querydsl.sql.dml.*;
  33. import static org.marvelution.jji.model.HasId.*;
  34. @Named
  35. public class DefaultBuildDAO
  36. extends AbstractPocketKnifeDAO<Build, BuildTable>
  37. implements BuildDAO
  38. {
  39. private final IssueReferenceProvider issueReferenceProvider;
  40. @Inject
  41. public DefaultBuildDAO(
  42. DatabaseAccessor databaseAccessor,
  43. StreamingQueryFactory queryFactory,
  44. IssueReferenceProvider issueReferenceProvider)
  45. {
  46. super(databaseAccessor, queryFactory, Tables.BUILD);
  47. this.issueReferenceProvider = issueReferenceProvider;
  48. }
  49. @Nullable
  50. @Override
  51. public Build get(String id)
  52. {
  53. return runInTransaction(conn -> findBuilds(conn, table.id().eq(id), 0, 1).stream().findFirst().orElse(null));
  54. }
  55. @Nullable
  56. @Override
  57. public Build get(
  58. String jobId,
  59. int buildNumber)
  60. {
  61. return runInTransaction(conn -> findBuilds(conn, table.jobId().eq(jobId).and(table.buildNumber().eq(buildNumber)), 0, 1).stream()
  62. .findFirst()
  63. .orElse(null));
  64. }
  65. @Override
  66. public Set<Build> getAllInRange(
  67. String jobId,
  68. int start,
  69. int end)
  70. {
  71. return runInTransaction(conn -> {
  72. BooleanExpression where = table.jobId().eq(jobId).and(table.buildNumber().goe(start));
  73. if (end > 0)
  74. {
  75. where = where.and(table.buildNumber().loe(end));
  76. }
  77. return findBuilds(conn, where, -1, -1);
  78. });
  79. }
  80. @Override
  81. public Set<Build> getAll(
  82. String jobId,
  83. int page,
  84. int size)
  85. {
  86. return runInTransaction(conn -> findBuilds(conn, table.jobId().eq(jobId), page, size));
  87. }
  88. @Override
  89. public Set<Build> getAllByJob(
  90. String jobId,
  91. int limit)
  92. {
  93. return runInTransaction(conn -> findBuilds(conn, table.jobId().eq(jobId), 0, limit));
  94. }
  95. protected Build saveInTransaction(
  96. Build build,
  97. DatabaseConnection conn)
  98. {
  99. // Create a copy and clear stuff not stored.
  100. Build copy = build.copy().setBranches(null).setChangeSet(null);
  101. super.saveInTransaction(copy, conn);
  102. conn.delete(Tables.TEST_RESULTS).where(Tables.TEST_RESULTS.buildId().eq(copy.getId())).execute();
  103. if (copy.getTestResults() != null)
  104. {
  105. TestResults testResults = copy.getTestResults();
  106. conn.insert(Tables.TEST_RESULTS)
  107. .set(Tables.TEST_RESULTS.id(), newId())
  108. .set(Tables.TEST_RESULTS.buildId(), copy.getId())
  109. .set(Tables.TEST_RESULTS.skipped(), testResults.getSkipped())
  110. .set(Tables.TEST_RESULTS.failed(), testResults.getFailed())
  111. .set(Tables.TEST_RESULTS.total(), testResults.getTotal())
  112. .execute();
  113. }
  114. conn.delete(Tables.BUILD_TO_DEPLOYMENT_ENVIRONMENT)
  115. .where(Tables.BUILD_TO_DEPLOYMENT_ENVIRONMENT.buildId().eq(copy.getId()))
  116. .execute();
  117. if (!copy.getDeploymentEnvironments().isEmpty())
  118. {
  119. List<String> knownDeployEnvironments = new ArrayList<>(
  120. conn.select(Tables.DEPLOYMENT_ENVIRONMENT.id()).from(Tables.DEPLOYMENT_ENVIRONMENT).fetch());
  121. SQLInsertClause insert = conn.insert(Tables.BUILD_TO_DEPLOYMENT_ENVIRONMENT);
  122. List<DeploymentEnvironment> deployEnvs = copy.getDeploymentEnvironments();
  123. for (DeploymentEnvironment deployEnv : deployEnvs)
  124. {
  125. if (!knownDeployEnvironments.contains(deployEnv.getId()))
  126. {
  127. Tables.DEPLOYMENT_ENVIRONMENT.insert(conn, deployEnv).execute();
  128. knownDeployEnvironments.add(deployEnv.getId());
  129. }
  130. insert.set(Tables.BUILD_TO_DEPLOYMENT_ENVIRONMENT.id(), newId())
  131. .set(Tables.BUILD_TO_DEPLOYMENT_ENVIRONMENT.buildId(), copy.getId())
  132. .set(Tables.BUILD_TO_DEPLOYMENT_ENVIRONMENT.environmentId(), deployEnv.getId())
  133. .addBatch();
  134. }
  135. insert.execute();
  136. }
  137. return copy;
  138. }
  139. @Override
  140. public void deleteAllByJob(String jobId)
  141. {
  142. runInTransaction(conn -> DeletionHelper.deleteJobBuilds(conn, jobId));
  143. }
  144. @Override
  145. public void delete(String id)
  146. {
  147. runInTransaction(conn -> DeletionHelper.deleteBuild(conn, id));
  148. }
  149. @Override
  150. public void markAsDeleted(String buildId)
  151. {
  152. runInTransaction(conn -> conn.update(table).set(table.deleted(), true).where(table.id().eq(buildId)).execute());
  153. }
  154. @Override
  155. public void markAllInJobAsDeleted(
  156. String jobId,
  157. int buildNumber)
  158. {
  159. runInTransaction(conn -> {
  160. BooleanExpression where = table.jobId().eq(jobId);
  161. if (buildNumber > 0)
  162. {
  163. where = where.and(table.buildNumber().lt(buildNumber));
  164. }
  165. conn.update(table).set(table.deleted(), true).where(where).execute();
  166. return null;
  167. });
  168. }
  169. @Override
  170. public Set<DeploymentEnvironment> getDeploymentEnvironments()
  171. {
  172. return new HashSet<>(
  173. runInTransaction(conn -> conn.select(new DeploymentEnvironmentProjection()).from(Tables.DEPLOYMENT_ENVIRONMENT).fetch()));
  174. }
  175. @Override
  176. public void cleanupOldDeletedBuilds(LocalDateTime timestamp)
  177. {
  178. databaseAccessor.runInTransaction(conn -> {
  179. String[] ids = conn.select(table.id())
  180. .from(table)
  181. .where(table.deleted().isTrue().and(table.timestamp().lt(TimeUtils.toEpochMilli(timestamp))))
  182. .fetch()
  183. .toArray(new String[0]);
  184. DeletionHelper.deleteBuild(conn, ids);
  185. return null;
  186. }, OnRollback.NOOP);
  187. }
  188. Set<Build> getBuilds(
  189. DatabaseConnection conn,
  190. Set<String> buildIds,
  191. boolean includeIssueReferences)
  192. {
  193. Set<Build> builds = findBuilds(conn, table.id().in(buildIds), -1, -1);
  194. if (includeIssueReferences)
  195. {
  196. for (Build build : builds)
  197. {
  198. build.setIssueReferences(conn.select(new IssueReferenceProjection(issueReferenceProvider))
  199. .from(Tables.ISSUE_TO_BUILD)
  200. .where(Tables.ISSUE_TO_BUILD.buildId().eq(build.getId()))
  201. .fetch());
  202. }
  203. }
  204. return builds;
  205. }
  206. Set<Build> findBuilds(
  207. DatabaseConnection conn,
  208. Predicate where,
  209. int page,
  210. int limit)
  211. {
  212. TreeSet<Build> builds = new TreeSet<>(Comparator.comparing(Build::getTimestamp).thenComparing(Build::getNumber));
  213. try (CloseableIterable<Build> results = queryFactory.stream(conn, () -> {
  214. SQLQuery<Build> query = conn.select(new BuildProjection())
  215. .from(table)
  216. .join(Tables.JOB)
  217. .on(table.jobId().eq(Tables.JOB.id()))
  218. .join(Tables.SITE)
  219. .on(Tables.JOB.siteId().eq(Tables.SITE.id()))
  220. .leftJoin(Tables.TEST_RESULTS)
  221. .on(table.id().eq(Tables.TEST_RESULTS.buildId()))
  222. .orderBy(table.timestamp().desc())
  223. .where(where);
  224. if (page >= 0 && limit > 0)
  225. {
  226. return query.offset((long) page * limit).limit(limit);
  227. }
  228. else
  229. {
  230. return query;
  231. }
  232. }))
  233. {
  234. results.foreach(builds::add);
  235. }
  236. for (Build build : builds)
  237. {
  238. build.setDeploymentEnvironments(conn.select(new DeploymentEnvironmentProjection())
  239. .from(Tables.BUILD_TO_DEPLOYMENT_ENVIRONMENT)
  240. .join(Tables.DEPLOYMENT_ENVIRONMENT)
  241. .on(Tables.BUILD_TO_DEPLOYMENT_ENVIRONMENT.environmentId()
  242. .eq(Tables.DEPLOYMENT_ENVIRONMENT.id()))
  243. .where(Tables.BUILD_TO_DEPLOYMENT_ENVIRONMENT.buildId().eq(build.getId()))
  244. .fetch());
  245. }
  246. return builds.descendingSet();
  247. }
  248. }