Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

PurgeCommands.java 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2023 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. package org.sonar.db.purge;
  21. import com.google.common.annotations.VisibleForTesting;
  22. import com.google.common.collect.Lists;
  23. import java.util.Collection;
  24. import java.util.List;
  25. import javax.annotation.Nullable;
  26. import org.sonar.api.utils.System2;
  27. import org.sonar.db.DbSession;
  28. import static org.sonar.db.DatabaseUtils.executeLargeInputs;
  29. class PurgeCommands {
  30. private static final int MAX_SNAPSHOTS_PER_QUERY = 1000;
  31. private static final int MAX_RESOURCES_PER_QUERY = 1000;
  32. private static final String[] UNPROCESSED_STATUS = new String[]{"U"};
  33. private final DbSession session;
  34. private final PurgeMapper purgeMapper;
  35. private final PurgeProfiler profiler;
  36. private final System2 system2;
  37. PurgeCommands(DbSession session, PurgeMapper purgeMapper, PurgeProfiler profiler, System2 system2) {
  38. this.session = session;
  39. this.purgeMapper = purgeMapper;
  40. this.profiler = profiler;
  41. this.system2 = system2;
  42. }
  43. PurgeCommands(DbSession session, PurgeProfiler profiler, System2 system2) {
  44. this(session, session.getMapper(PurgeMapper.class), profiler, system2);
  45. }
  46. List<String> selectSnapshotUuids(PurgeSnapshotQuery query) {
  47. return purgeMapper.selectAnalysisUuids(query);
  48. }
  49. void deleteEventComponentChanges(String rootComponentUuid) {
  50. profiler.start("deleteAnalyses (event_component_changes)");
  51. purgeMapper.deleteEventComponentChangesByComponentUuid(rootComponentUuid);
  52. session.commit();
  53. profiler.stop();
  54. }
  55. void deleteAnalyses(String rootComponentUuid) {
  56. profiler.start("deleteAnalyses (events)");
  57. purgeMapper.deleteEventsByComponentUuid(rootComponentUuid);
  58. session.commit();
  59. profiler.stop();
  60. List<List<String>> analysisUuidsPartitions = Lists.partition(purgeMapper.selectAnalysisUuids(new PurgeSnapshotQuery(rootComponentUuid)), MAX_SNAPSHOTS_PER_QUERY);
  61. deleteAnalysisDuplications(analysisUuidsPartitions);
  62. profiler.start("deleteAnalyses (project_measures)");
  63. analysisUuidsPartitions.forEach(purgeMapper::deleteAnalysisMeasures);
  64. session.commit();
  65. profiler.stop();
  66. profiler.start("deleteAnalyses (analysis_properties)");
  67. analysisUuidsPartitions.forEach(purgeMapper::deleteAnalysisProperties);
  68. session.commit();
  69. profiler.stop();
  70. profiler.start("deleteAnalyses (snapshots)");
  71. analysisUuidsPartitions.forEach(purgeMapper::deleteAnalyses);
  72. session.commit();
  73. profiler.stop();
  74. }
  75. void deleteAbortedAnalyses(String rootUuid) {
  76. PurgeSnapshotQuery query = new PurgeSnapshotQuery(rootUuid)
  77. .setIslast(false)
  78. .setStatus(UNPROCESSED_STATUS);
  79. deleteAnalyses(purgeMapper.selectAnalysisUuids(query));
  80. }
  81. @VisibleForTesting
  82. void deleteAnalyses(List<String> analysisIdUuids) {
  83. List<List<String>> analysisUuidsPartitions = Lists.partition(analysisIdUuids, MAX_SNAPSHOTS_PER_QUERY);
  84. deleteAnalysisDuplications(analysisUuidsPartitions);
  85. profiler.start("deleteAnalyses (event_component_changes)");
  86. analysisUuidsPartitions.forEach(purgeMapper::deleteAnalysisEventComponentChanges);
  87. session.commit();
  88. profiler.stop();
  89. profiler.start("deleteAnalyses (events)");
  90. analysisUuidsPartitions.forEach(purgeMapper::deleteAnalysisEvents);
  91. session.commit();
  92. profiler.stop();
  93. profiler.start("deleteAnalyses (project_measures)");
  94. analysisUuidsPartitions.forEach(purgeMapper::deleteAnalysisMeasures);
  95. session.commit();
  96. profiler.stop();
  97. profiler.start("deleteAnalyses (analysis_properties)");
  98. analysisUuidsPartitions.forEach(purgeMapper::deleteAnalysisProperties);
  99. session.commit();
  100. profiler.stop();
  101. profiler.start("deleteAnalyses (snapshots)");
  102. analysisUuidsPartitions.forEach(purgeMapper::deleteAnalyses);
  103. session.commit();
  104. profiler.stop();
  105. }
  106. void purgeAnalyses(List<String> analysisUuids) {
  107. List<List<String>> analysisUuidsPartitions = Lists.partition(analysisUuids, MAX_SNAPSHOTS_PER_QUERY);
  108. deleteAnalysisDuplications(analysisUuidsPartitions);
  109. profiler.start("updatePurgeStatusToOne (snapshots)");
  110. analysisUuidsPartitions.forEach(purgeMapper::updatePurgeStatusToOne);
  111. session.commit();
  112. profiler.stop();
  113. }
  114. void purgeDisabledComponents(String rootComponentUuid, Collection<String> disabledComponentUuids, PurgeListener listener) {
  115. profiler.start("purgeDisabledComponents (file_sources)");
  116. executeLargeInputs(
  117. purgeMapper.selectDisabledComponentsWithFileSource(rootComponentUuid),
  118. input -> {
  119. purgeMapper.deleteFileSourcesByFileUuid(input);
  120. return input;
  121. });
  122. profiler.stop();
  123. profiler.start("purgeDisabledComponents (unresolved_issues)");
  124. executeLargeInputs(
  125. purgeMapper.selectDisabledComponentsWithUnresolvedIssues(rootComponentUuid),
  126. input -> {
  127. purgeMapper.resolveComponentIssuesNotAlreadyResolved(input, system2.now());
  128. return input;
  129. });
  130. profiler.stop();
  131. profiler.start("purgeDisabledComponents (live_measures)");
  132. executeLargeInputs(
  133. purgeMapper.selectDisabledComponentsWithLiveMeasures(rootComponentUuid),
  134. input -> {
  135. purgeMapper.deleteLiveMeasuresByComponentUuids(input);
  136. return input;
  137. });
  138. profiler.stop();
  139. session.commit();
  140. }
  141. private void deleteAnalysisDuplications(List<List<String>> snapshotUuidsPartitions) {
  142. profiler.start("deleteAnalysisDuplications (duplications_index)");
  143. snapshotUuidsPartitions.forEach(purgeMapper::deleteAnalysisDuplications);
  144. session.commit();
  145. profiler.stop();
  146. }
  147. void deletePermissions(String entityUuid) {
  148. profiler.start("deletePermissions (group_roles)");
  149. purgeMapper.deleteGroupRolesByEntityUuid(entityUuid);
  150. session.commit();
  151. profiler.stop();
  152. profiler.start("deletePermissions (user_roles)");
  153. purgeMapper.deleteUserRolesByEntityUuid(entityUuid);
  154. session.commit();
  155. profiler.stop();
  156. }
  157. void deleteIssues(String rootUuid) {
  158. profiler.start("deleteIssues (issue_changes)");
  159. purgeMapper.deleteIssueChangesByProjectUuid(rootUuid);
  160. session.commit();
  161. profiler.stop();
  162. profiler.start("deleteIssues (new_code_reference_issues)");
  163. purgeMapper.deleteNewCodeReferenceIssuesByProjectUuid(rootUuid);
  164. session.commit();
  165. profiler.stop();
  166. profiler.start("deleteIssues (issues_impacts)");
  167. purgeMapper.deleteIssuesImpactsByProjectUuid(rootUuid);
  168. session.commit();
  169. profiler.stop();
  170. profiler.start("deleteIssues (issues)");
  171. purgeMapper.deleteIssuesByProjectUuid(rootUuid);
  172. session.commit();
  173. profiler.stop();
  174. }
  175. void deleteLinks(String rootUuid) {
  176. profiler.start("deleteLinks (project_links)");
  177. purgeMapper.deleteProjectLinksByProjectUuid(rootUuid);
  178. session.commit();
  179. profiler.stop();
  180. }
  181. void deleteByRootAndSubviews(List<String> rootAndSubviewsUuids) {
  182. if (rootAndSubviewsUuids.isEmpty()) {
  183. return;
  184. }
  185. List<List<String>> uuidsPartitions = Lists.partition(rootAndSubviewsUuids, MAX_RESOURCES_PER_QUERY);
  186. profiler.start("deleteByRootAndSubviews (properties)");
  187. uuidsPartitions.forEach(purgeMapper::deletePropertiesByEntityUuids);
  188. session.commit();
  189. profiler.stop();
  190. profiler.start("deleteByRootAndSubviews (report_schedules)");
  191. uuidsPartitions.forEach(purgeMapper::deleteReportSchedulesByPortfolioUuids);
  192. session.commit();
  193. profiler.stop();
  194. profiler.start("deleteByRootAndSubviews (report_subscriptions)");
  195. uuidsPartitions.forEach(purgeMapper::deleteReportSubscriptionsByPortfolioUuids);
  196. session.commit();
  197. profiler.stop();
  198. }
  199. void deleteDisabledComponentsWithoutIssues(List<String> disabledComponentsWithoutIssue) {
  200. if (disabledComponentsWithoutIssue.isEmpty()) {
  201. return;
  202. }
  203. List<List<String>> uuidsPartitions = Lists.partition(disabledComponentsWithoutIssue, MAX_RESOURCES_PER_QUERY);
  204. profiler.start("deleteDisabledComponentsWithoutIssues (properties)");
  205. uuidsPartitions.forEach(purgeMapper::deletePropertiesByEntityUuids);
  206. session.commit();
  207. profiler.stop();
  208. profiler.start("deleteDisabledComponentsWithoutIssues (projects)");
  209. uuidsPartitions.forEach(purgeMapper::deleteComponentsByUuids);
  210. session.commit();
  211. profiler.stop();
  212. }
  213. void deleteOutdatedProperties(String entityUuid) {
  214. profiler.start("deleteOutdatedProperties (properties)");
  215. purgeMapper.deletePropertiesByEntityUuids(List.of(entityUuid));
  216. session.commit();
  217. profiler.stop();
  218. }
  219. void deleteComponents(String rootUuid) {
  220. profiler.start("deleteComponents (projects)");
  221. purgeMapper.deleteComponentsByBranchUuid(rootUuid);
  222. session.commit();
  223. profiler.stop();
  224. }
  225. void deleteNonMainBranchComponentsByProjectUuid(String uuid) {
  226. profiler.start("deleteNonMainBranchComponentsByProjectUuid (projects)");
  227. purgeMapper.deleteNonMainBranchComponentsByProjectUuid(uuid);
  228. session.commit();
  229. profiler.stop();
  230. }
  231. void deleteProject(String projectUuid) {
  232. profiler.start("deleteProject (projects)");
  233. purgeMapper.deleteProjectsByProjectUuid(projectUuid);
  234. session.commit();
  235. profiler.stop();
  236. }
  237. void deleteComponents(List<String> componentUuids) {
  238. if (componentUuids.isEmpty()) {
  239. return;
  240. }
  241. profiler.start("deleteComponents (projects)");
  242. Lists.partition(componentUuids, MAX_RESOURCES_PER_QUERY).forEach(purgeMapper::deleteComponentsByUuids);
  243. session.commit();
  244. profiler.stop();
  245. }
  246. void deleteComponentMeasures(List<String> componentUuids) {
  247. if (componentUuids.isEmpty()) {
  248. return;
  249. }
  250. profiler.start("deleteComponentMeasures (project_measures)");
  251. Lists.partition(componentUuids, MAX_RESOURCES_PER_QUERY).forEach(purgeMapper::fullDeleteComponentMeasures);
  252. session.commit();
  253. profiler.stop();
  254. }
  255. void deleteFileSources(String rootUuid) {
  256. profiler.start("deleteFileSources (file_sources)");
  257. purgeMapper.deleteFileSourcesByProjectUuid(rootUuid);
  258. session.commit();
  259. profiler.stop();
  260. }
  261. void deleteCeActivity(String rootUuid) {
  262. profiler.start("deleteCeActivity (ce_scanner_context)");
  263. purgeMapper.deleteCeScannerContextOfCeActivityByRootUuidOrBefore(rootUuid, null, null);
  264. session.commit();
  265. profiler.stop();
  266. profiler.start("deleteCeActivity (ce_task_characteristics)");
  267. purgeMapper.deleteCeTaskCharacteristicsOfCeActivityByRootUuidOrBefore(rootUuid, null, null);
  268. session.commit();
  269. profiler.stop();
  270. profiler.start("deleteCeActivity (ce_task_input)");
  271. purgeMapper.deleteCeTaskInputOfCeActivityByRootUuidOrBefore(rootUuid, null, null);
  272. session.commit();
  273. profiler.stop();
  274. profiler.start("deleteCeActivity (ce_task_message)");
  275. purgeMapper.deleteCeTaskMessageOfCeActivityByRootUuidOrBefore(rootUuid, null, null);
  276. session.commit();
  277. profiler.stop();
  278. profiler.start("deleteCeActivity (ce_activity)");
  279. purgeMapper.deleteCeActivityByRootUuidOrBefore(rootUuid, null, null);
  280. session.commit();
  281. profiler.stop();
  282. }
  283. void deleteCeActivityBefore(@Nullable String rootUuid, @Nullable String entityUuidToPurge, long createdAt) {
  284. profiler.start("deleteCeActivityBefore (ce_scanner_context)");
  285. purgeMapper.deleteCeScannerContextOfCeActivityByRootUuidOrBefore(rootUuid, entityUuidToPurge, createdAt);
  286. session.commit();
  287. profiler.stop();
  288. profiler.start("deleteCeActivityBefore (ce_task_characteristics)");
  289. purgeMapper.deleteCeTaskCharacteristicsOfCeActivityByRootUuidOrBefore(rootUuid, entityUuidToPurge, createdAt);
  290. session.commit();
  291. profiler.stop();
  292. profiler.start("deleteCeActivityBefore (ce_task_input)");
  293. purgeMapper.deleteCeTaskInputOfCeActivityByRootUuidOrBefore(rootUuid, entityUuidToPurge, createdAt);
  294. session.commit();
  295. profiler.stop();
  296. profiler.start("deleteCeActivityBefore (ce_task_message)");
  297. purgeMapper.deleteCeTaskMessageOfCeActivityByRootUuidOrBefore(rootUuid, entityUuidToPurge, createdAt);
  298. session.commit();
  299. profiler.stop();
  300. profiler.start("deleteCeActivityBefore (ce_activity)");
  301. purgeMapper.deleteCeActivityByRootUuidOrBefore(rootUuid, entityUuidToPurge, createdAt);
  302. session.commit();
  303. profiler.stop();
  304. }
  305. void deleteCeScannerContextBefore(@Nullable String rootUuid, @Nullable String entityUuidToPurge, long createdAt) {
  306. // assuming CeScannerContext of rows in table CE_QUEUE can't be older than createdAt
  307. profiler.start("deleteCeScannerContextBefore");
  308. purgeMapper.deleteCeScannerContextOfCeActivityByRootUuidOrBefore(rootUuid, entityUuidToPurge, createdAt);
  309. session.commit();
  310. }
  311. void deleteCeQueue(String rootUuid) {
  312. profiler.start("deleteCeQueue (ce_scanner_context)");
  313. purgeMapper.deleteCeScannerContextOfCeQueueByRootUuid(rootUuid);
  314. session.commit();
  315. profiler.stop();
  316. profiler.start("deleteCeQueue (ce_task_characteristics)");
  317. purgeMapper.deleteCeTaskCharacteristicsOfCeQueueByRootUuid(rootUuid);
  318. session.commit();
  319. profiler.stop();
  320. profiler.start("deleteCeQueue (ce_task_input)");
  321. purgeMapper.deleteCeTaskInputOfCeQueueByRootUuid(rootUuid);
  322. session.commit();
  323. profiler.stop();
  324. profiler.start("deleteCeQueue (ce_task_message)");
  325. purgeMapper.deleteCeTaskMessageOfCeQueueByRootUuid(rootUuid);
  326. session.commit();
  327. profiler.stop();
  328. profiler.start("deleteCeQueue (ce_queue)");
  329. purgeMapper.deleteCeQueueByRootUuid(rootUuid);
  330. session.commit();
  331. profiler.stop();
  332. }
  333. void deleteWebhooks(String rootUuid) {
  334. profiler.start("deleteWebhooks (webhooks)");
  335. purgeMapper.deleteWebhooksByProjectUuid(rootUuid);
  336. session.commit();
  337. profiler.stop();
  338. }
  339. void deleteWebhookDeliveries(String rootUuid) {
  340. profiler.start("deleteWebhookDeliveries (webhook_deliveries)");
  341. purgeMapper.deleteWebhookDeliveriesByProjectUuid(rootUuid);
  342. session.commit();
  343. profiler.stop();
  344. }
  345. void deleteApplicationProjectsByProject(String projectUuid) {
  346. profiler.start("deleteApplicationProjectsByProject (app_projects)");
  347. purgeMapper.deleteAppBranchProjectBranchesByProjectUuid(projectUuid);
  348. purgeMapper.deleteAppProjectsByProjectUuid(projectUuid);
  349. session.commit();
  350. profiler.stop();
  351. }
  352. void deleteApplicationProjects(String applicationUuid) {
  353. profiler.start("deleteApplicationProjects (app_projects)");
  354. purgeMapper.deleteAppBranchProjectBranchesByAppUuid(applicationUuid);
  355. purgeMapper.deleteAppProjectsByAppUuid(applicationUuid);
  356. session.commit();
  357. profiler.stop();
  358. }
  359. void deleteApplicationBranchProjects(String applicationBranchUuid) {
  360. profiler.start("deleteApplicationBranchProjects (app_branch_project_branch)");
  361. purgeMapper.deleteAppBranchProjectsByAppBranchUuid(applicationBranchUuid);
  362. session.commit();
  363. profiler.stop();
  364. }
  365. public void deleteProjectAlmSettings(String rootUuid) {
  366. profiler.start("deleteProjectAlmSettings (project_alm_settings)");
  367. purgeMapper.deleteProjectAlmSettingsByProjectUuid(rootUuid);
  368. session.commit();
  369. profiler.stop();
  370. }
  371. public void deleteProjectBadgeToken(String rootUuid) {
  372. profiler.start("deleteProjectBadgeToken (project_badge_token)");
  373. purgeMapper.deleteProjectBadgeTokenByProjectUuid(rootUuid);
  374. session.commit();
  375. profiler.stop();
  376. }
  377. void deleteBranch(String rootUuid) {
  378. profiler.start("deleteBranch (project_branches)");
  379. purgeMapper.deleteAppBranchProjectBranchesByProjectBranchUuid(rootUuid);
  380. purgeMapper.deleteBranchByUuid(rootUuid);
  381. session.commit();
  382. profiler.stop();
  383. }
  384. void deleteLiveMeasures(String rootUuid) {
  385. profiler.start("deleteLiveMeasures (live_measures)");
  386. purgeMapper.deleteLiveMeasuresByProjectUuid(rootUuid);
  387. session.commit();
  388. profiler.stop();
  389. }
  390. void deleteNewCodePeriodsForProject(String projectUuid) {
  391. profiler.start("deleteNewCodePeriods (new_code_periods)");
  392. purgeMapper.deleteNewCodePeriodsByProjectUuid(projectUuid);
  393. session.commit();
  394. profiler.stop();
  395. }
  396. void deleteNewCodePeriodsForBranch(String branchUuid) {
  397. profiler.start("deleteNewCodePeriods (new_code_periods)");
  398. purgeMapper.deleteNewCodePeriodsByBranchUuid(branchUuid);
  399. session.commit();
  400. profiler.stop();
  401. }
  402. void deleteUserDismissedMessages(String projectUuid) {
  403. profiler.start("deleteUserDismissedMessages (user_dismissed_messages)");
  404. purgeMapper.deleteUserDismissedMessagesByProjectUuid(projectUuid);
  405. session.commit();
  406. profiler.stop();
  407. }
  408. public void deleteProjectInPortfolios(String rootUuid) {
  409. profiler.start("deleteProjectInPortfolios (portfolio_projects)");
  410. // delete selected project if it's only selecting a single branch corresponding to rootUuid
  411. purgeMapper.deletePortfolioProjectsByBranchUuid(rootUuid);
  412. // delete selected branches if branch is rootUuid or if it's part of a project that is rootUuid
  413. purgeMapper.deletePortfolioProjectBranchesByBranchUuid(rootUuid);
  414. // delete selected project if project is rootUuid
  415. purgeMapper.deletePortfolioProjectsByProjectUuid(rootUuid);
  416. session.commit();
  417. profiler.stop();
  418. }
  419. public void deleteScannerCache(String branchUuid) {
  420. profiler.start("deleteScannerCache (scanner_analysis_cache)");
  421. purgeMapper.deleteScannerAnalysisCacheByBranchUuid(branchUuid);
  422. session.commit();
  423. profiler.stop();
  424. }
  425. public void deleteReportSchedules(String rootUuid) {
  426. profiler.start("deleteReportSchedules (report_schedules)");
  427. purgeMapper.deleteReportSchedulesByBranchUuid(rootUuid);
  428. session.commit();
  429. profiler.stop();
  430. }
  431. public void deleteReportSubscriptions(String branchUuid) {
  432. profiler.start("deleteReportSubscriptions (report_subscriptions)");
  433. purgeMapper.deleteReportSubscriptionsByBranchUuid(branchUuid);
  434. session.commit();
  435. profiler.stop();
  436. }
  437. public void deleteAnticipatedTransitions(String projectUuid, long createdAt) {
  438. profiler.start("deleteAnticipatedTransitions (anticipated_transitions)");
  439. purgeMapper.deleteAnticipatedTransitionsByProjectUuidAndCreationDate(projectUuid, createdAt);
  440. session.commit();
  441. profiler.stop();
  442. }
  443. }