Merge branch '29-statistic-filter' into 'master'
Resolve "фильтр в статистике" Closes #29 See merge request romanov73/git-extractor!28
This commit is contained in:
commit
571e51fc64
@ -8,10 +8,15 @@ package ru.ulstu.extractor.controller;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import ru.ulstu.extractor.model.mvc.FilterForm;
|
||||
import ru.ulstu.extractor.repository.CommitRepository;
|
||||
import ru.ulstu.extractor.service.BranchService;
|
||||
import ru.ulstu.extractor.service.FilteringService;
|
||||
import springfox.documentation.annotations.ApiIgnore;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static ru.ulstu.extractor.controller.Route.STATISTIC;
|
||||
@ -20,16 +25,26 @@ import static ru.ulstu.extractor.controller.Route.STATISTIC;
|
||||
@ApiIgnore
|
||||
public class StatisticController {
|
||||
private final CommitRepository commitRepository;
|
||||
private final FilteringService filteringService;
|
||||
private final BranchService branchService;
|
||||
|
||||
public StatisticController(CommitRepository commitRepository) {
|
||||
public StatisticController(CommitRepository commitRepository,
|
||||
FilteringService filteringService,
|
||||
BranchService branchService) {
|
||||
this.commitRepository = commitRepository;
|
||||
this.filteringService = filteringService;
|
||||
this.branchService = branchService;
|
||||
}
|
||||
|
||||
@GetMapping(STATISTIC)
|
||||
public String indexBranch(Model model) {
|
||||
public String getStatistic(Model model,
|
||||
@RequestParam Optional<Integer> branchId,
|
||||
@RequestParam Optional<String> author,
|
||||
@RequestParam Optional<String> filter,
|
||||
@RequestParam Optional<Boolean> entity) {
|
||||
List<Object[]> urlCommits = getUrlCommits();
|
||||
List<Object[]> timeCommits = getTimeCommits();
|
||||
model.addAttribute("commitAuthorData", authorCommits());
|
||||
List<Object[]> timeCommits = getTimeCommits(branchId, author);
|
||||
model.addAttribute("commitAuthorData", authorCommits(branchId, author));
|
||||
model.addAttribute("commitUrlData", urlCommits);
|
||||
model.addAttribute("commitTimeData", timeCommits);
|
||||
List<String> dates = timeCommits.stream()
|
||||
@ -41,13 +56,25 @@ public class StatisticController {
|
||||
.map(tc -> tc[0].toString().substring(tc[0].toString().lastIndexOf("/") + 1))
|
||||
.collect(Collectors.toList());
|
||||
model.addAttribute("urls", urls);
|
||||
model.addAttribute("commitEntityData", getEntityCommits());
|
||||
model.addAttribute("commitTimeEntityData", allTimeEntityCommits());
|
||||
model.addAttribute("commitEntityData", getEntityCommits(branchId, author));
|
||||
model.addAttribute("commitTimeEntityData", allTimeEntityCommits(branchId, author));
|
||||
FilterForm filterForm = new FilterForm();
|
||||
filterForm.setBranchId(branchId.orElse(null));
|
||||
filterForm.setAuthor(author.orElse(null));
|
||||
filterForm.setFilter(filter.orElse(null));
|
||||
filterForm.setEntity(entity.orElse(null));
|
||||
model.addAttribute("filterForm", filterForm);
|
||||
model.addAttribute("entityPresent", filteringService.getEntityPresent());
|
||||
model.addAttribute("branches", branchService.findAll());
|
||||
model.addAttribute("authors", filteringService.getRepositoryAuthors(branchId.orElse(null)));
|
||||
return STATISTIC;
|
||||
}
|
||||
|
||||
public List<Object[]> authorCommits() {
|
||||
return commitRepository.getCommitAuthorStatistic().stream()
|
||||
public List<Object[]> authorCommits(Optional<Integer> branchId, Optional<String> author) {
|
||||
return commitRepository.getCommitAuthorStatistic(
|
||||
branchId.orElse(null),
|
||||
author.orElse(null))
|
||||
.stream()
|
||||
.map(stat -> new Object[]{stat.getAuthor(), stat.getCountCommit()})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
@ -58,14 +85,14 @@ public class StatisticController {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<Object[]> getTimeCommits() {
|
||||
return commitRepository.getCommitTimeStatistic().stream()
|
||||
public List<Object[]> getTimeCommits(Optional<Integer> branchId, Optional<String> author) {
|
||||
return commitRepository.getCommitTimeStatistic(branchId.orElse(null), author.orElse(null)).stream()
|
||||
.map(stat -> new Object[]{stat.getDate(), stat.getCountCommit()})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<Object[]> getEntityCommits() {
|
||||
List<Object[]> entityCommits = commitRepository.getCommitEntityStatistic().stream()
|
||||
public List<Object[]> getEntityCommits(Optional<Integer> branchId, Optional<String> author) {
|
||||
List<Object[]> entityCommits = commitRepository.getCommitEntityStatistic(branchId.orElse(null), author.orElse(null)).stream()
|
||||
.map(stat -> new Object[]{stat.getEntity(), stat.getCountCommit()})
|
||||
.collect(Collectors.toList());
|
||||
for (Object[] entityCommit : entityCommits) {
|
||||
@ -78,15 +105,15 @@ public class StatisticController {
|
||||
return entityCommits;
|
||||
}
|
||||
|
||||
public List<Object[]> getTimeEntityCommits() {
|
||||
return commitRepository.getCommitTimeEntityStatistic().stream()
|
||||
public List<Object[]> getTimeEntityCommits(Optional<Integer> branchId, Optional<String> author) {
|
||||
return commitRepository.getCommitTimeEntityStatistic(branchId.orElse(null), author.orElse(null)).stream()
|
||||
.map(stat -> new Object[]{stat.getDate(), stat.getCountCommit()})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<Object[]> allTimeEntityCommits() {
|
||||
List<Object[]> timeEntityCommits = getTimeEntityCommits();
|
||||
List<Object[]> allTimeEntityCommits = commitRepository.getCommitTimeStatistic().stream()
|
||||
public List<Object[]> allTimeEntityCommits(Optional<Integer> branchId, Optional<String> author) {
|
||||
List<Object[]> timeEntityCommits = getTimeEntityCommits(branchId, author);
|
||||
List<Object[]> allTimeEntityCommits = commitRepository.getCommitTimeStatistic(branchId.orElse(null), author.orElse(null)).stream()
|
||||
.map(stat -> new Object[]{stat.getDate(), stat.getCountCommit()})
|
||||
.collect(Collectors.toList());
|
||||
int j = 0;
|
||||
|
@ -12,6 +12,7 @@ public class FilterForm {
|
||||
private String filter;
|
||||
private String repositoryUrl;
|
||||
private String branchName;
|
||||
private Integer branchId;
|
||||
private String author;
|
||||
private Boolean entity;
|
||||
private Page<Commit> commitsPage;
|
||||
@ -71,6 +72,14 @@ public class FilterForm {
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
public Integer getBranchId() {
|
||||
return branchId;
|
||||
}
|
||||
|
||||
public void setBranchId(Integer branchId) {
|
||||
this.branchId = branchId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FilterForm{" +
|
||||
|
@ -14,8 +14,11 @@ import ru.ulstu.extractor.model.Repository;
|
||||
import java.util.List;
|
||||
|
||||
public interface AuthorRepository extends JpaRepository<Author, Integer> {
|
||||
@Query("SELECT DISTINCT a.name FROM Commit c, Repository r, Branch b, Author a WHERE c.author = a AND c.branch = b AND r = b.repository AND r = :repository AND b.name = :branchName AND a.name IS NOT NULL AND a.name <> '' ORDER BY a.name")
|
||||
@Query("SELECT DISTINCT a.name FROM Commit c, Repository r, Branch b, Author a WHERE c.author = a AND c.branch = b AND r = b.repository AND (:repository IS NULL OR r = :repository) AND (:branchName IS NULL OR :branchName = '' OR b.name = :branchName) AND a.name IS NOT NULL AND a.name <> '' ORDER BY a.name")
|
||||
List<String> findByRepositoryAndBranch(@Param("repository") Repository repository, @Param("branchName") String branchName);
|
||||
|
||||
List<Author> findByName(String name);
|
||||
|
||||
@Query("SELECT DISTINCT a.name FROM Commit c, Branch b, Author a WHERE c.author = a AND c.branch = b AND (:branchId IS NULL OR b.id = :branchId) AND a.name IS NOT NULL AND a.name <> '' ORDER BY a.name")
|
||||
List<String> findByBranchId(Integer branchId);
|
||||
}
|
||||
|
@ -23,20 +23,20 @@ public interface CommitRepository extends JpaRepository<Commit, Integer> {
|
||||
@Query("SELECT DISTINCT c FROM Commit c LEFT JOIN c.branch b LEFT JOIN c.fileChanges f LEFT JOIN c.author a LEFT JOIN b.repository r WHERE r = :repository AND b.name = :branchName AND (:author IS NULL OR :author = '' OR a.name = :author) AND (:filter IS NULL OR :filter = '' OR lower(c.message) LIKE lower(concat('%', :filter,'%'))) AND (:entity IS NULL OR f.containsEntity = :entity)")
|
||||
Page<Commit> findByRepositoryAndBranch(Pageable pageable, @Param("repository") Repository repository, @Param("branchName") String branchName, @Param("author") String author, @Param("filter") String filter, @Param("entity") Boolean entity);
|
||||
|
||||
@Query("SELECT new ru.ulstu.extractor.model.CommitAuthorStatistic(c.author.name, COUNT(DISTINCT c.hash)) FROM Commit c GROUP by c.author.name")
|
||||
List<CommitAuthorStatistic> getCommitAuthorStatistic();
|
||||
@Query("SELECT new ru.ulstu.extractor.model.CommitAuthorStatistic(c.author.name, COUNT(DISTINCT c.hash)) FROM Commit c LEFT JOIN c.branch LEFT JOIN c.author a WHERE (:branchId IS NULL OR c.branch.id = :branchId) AND (:author IS NULL OR :author = '' OR a.name = :author) GROUP by c.author.name")
|
||||
List<CommitAuthorStatistic> getCommitAuthorStatistic(@Param("branchId") Integer branchId, @Param("author") String author);
|
||||
|
||||
@Query("SELECT new ru.ulstu.extractor.model.CommitUrlStatistic(c.branch.repository.url, COUNT(DISTINCT c.hash)) FROM Commit c GROUP by c.branch.repository.url")
|
||||
List<CommitUrlStatistic> getCommitUrlStatistic();
|
||||
|
||||
@Query("SELECT new ru.ulstu.extractor.model.CommitTimeStatistic(extract(month FROM c.date) as month, extract(year FROM c.date) as year, COUNT(DISTINCT c.hash)) FROM Commit c GROUP by extract(month from c.date), extract(year from c.date) ORDER by extract(year from c.date), extract(month from c.date)")
|
||||
List<CommitTimeStatistic> getCommitTimeStatistic();
|
||||
@Query("SELECT new ru.ulstu.extractor.model.CommitTimeStatistic(extract(month FROM c.date) as month, extract(year FROM c.date) as year, COUNT(DISTINCT c.hash)) FROM Commit c LEFT JOIN c.branch LEFT JOIN c.author a WHERE (:branchId IS NULL OR c.branch.id = :branchId) AND (:author IS NULL OR :author = '' OR a.name = :author) GROUP by extract(month from c.date), extract(year from c.date) ORDER by extract(year from c.date), extract(month from c.date)")
|
||||
List<CommitTimeStatistic> getCommitTimeStatistic(@Param("branchId") Integer branchId, @Param("author") String author);
|
||||
|
||||
@Query("SELECT new ru.ulstu.extractor.model.CommitEntityStatistic(f.containsEntity, COUNT(DISTINCT c.hash)) FROM Commit c JOIN c.fileChanges f GROUP by f.containsEntity")
|
||||
List<CommitEntityStatistic> getCommitEntityStatistic();
|
||||
@Query("SELECT new ru.ulstu.extractor.model.CommitEntityStatistic(f.containsEntity, COUNT(DISTINCT c.hash)) FROM Commit c LEFT JOIN c.branch LEFT JOIN c.author a LEFT JOIN c.fileChanges f WHERE (:branchId IS NULL OR c.branch.id = :branchId) AND (:author IS NULL OR :author = '' OR a.name = :author) GROUP by f.containsEntity")
|
||||
List<CommitEntityStatistic> getCommitEntityStatistic(@Param("branchId") Integer branchId, @Param("author") String author);
|
||||
|
||||
@Query("SELECT new ru.ulstu.extractor.model.CommitTimeStatistic(EXTRACT(MONTH FROM c.date), EXTRACT(YEAR FROM c.date), COUNT(DISTINCT c.hash)) FROM Commit c JOIN c.fileChanges f WHERE f.containsEntity = true GROUP by extract(month from c.date), extract(year from c.date) ORDER by extract(year from c.date), extract(month from c.date)")
|
||||
List<CommitTimeStatistic> getCommitTimeEntityStatistic();
|
||||
@Query("SELECT new ru.ulstu.extractor.model.CommitTimeStatistic(EXTRACT(MONTH FROM c.date), EXTRACT(YEAR FROM c.date), COUNT(DISTINCT c.hash)) FROM Commit c LEFT JOIN c.branch LEFT JOIN c.author a LEFT JOIN c.fileChanges f WHERE f.containsEntity = true AND (:branchId IS NULL OR c.branch.id = :branchId) AND (:author IS NULL OR :author = '' OR a.name = :author) GROUP by extract(month from c.date), extract(year from c.date) ORDER by extract(year from c.date), extract(month from c.date)")
|
||||
List<CommitTimeStatistic> getCommitTimeEntityStatistic(@Param("branchId") Integer branchId, @Param("author") String author);
|
||||
|
||||
void deleteByBranchIsNull();
|
||||
}
|
||||
|
@ -51,4 +51,8 @@ public class BranchService {
|
||||
public Branch findByRepositoryAndName(Repository repository, String branchName) {
|
||||
return branchRepository.findByRepositoryAndName(repository, branchName);
|
||||
}
|
||||
|
||||
public List<Branch> findAll() {
|
||||
return branchRepository.findAll();
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +39,10 @@ public class FilteringService {
|
||||
);
|
||||
}
|
||||
|
||||
public List<String> getRepositoryAuthors(Integer branchId) {
|
||||
return authorRepository.findByBranchId(branchId);
|
||||
}
|
||||
|
||||
public Page<Commit> getCommits(@NotNull String repositoryUrl,
|
||||
@NotNull String branchName,
|
||||
String author,
|
||||
|
@ -78,6 +78,7 @@
|
||||
json.plotOptions = plotOptions;
|
||||
$('#container').highcharts(json);
|
||||
});
|
||||
|
||||
</script>
|
||||
<script th:inline="javascript">
|
||||
$(document).ready(function () {
|
||||
@ -135,6 +136,7 @@
|
||||
$('#containerColumn').highcharts(json);
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
<script th:inline="javascript">
|
||||
function createPie(data, title) {
|
||||
@ -177,12 +179,85 @@
|
||||
$('#containerPie').highcharts(createPie([[${commitAuthorData}]], '% коммитов авторов'));
|
||||
$('#containerEntityPie').highcharts(createPie([[${commitEntityData}]], '% коммитов содержащих сущности'));
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
<div class="row">
|
||||
<div id="container" style="width: 550px; height: 400px; margin: 0 auto"></div>
|
||||
<div id="containerPie" style="width: 550px; height: 400px; margin: 0 auto"></div>
|
||||
<div id="containerColumn" style="width: 550px; height: 400px; margin: 0 auto"></div>
|
||||
<div id="containerEntityPie" style="width: 550px; height: 400px; margin: 0 auto"></div>
|
||||
</div>
|
||||
<form action="#" th:action="${@route.STATISTIC}" th:object="${filterForm}" method="get">
|
||||
<div class="row">
|
||||
<div class="col-md-2 col-sm-12">
|
||||
Репозиторий-ветка
|
||||
</div>
|
||||
<div class="col-md-6 col-sm-12">
|
||||
<select id="select-branch" class="selectpicker" data-live-search="true" th:field="*{branchId}"
|
||||
data-width="90%">
|
||||
<option value="">Все ветки</option>
|
||||
<option th:each="branch : ${branches}"
|
||||
th:value="${branch.id}"
|
||||
th:utext="${branch.repository.url} + ' - '+ ${branch.name}">
|
||||
</option>
|
||||
</select>
|
||||
<script th:inline="javascript">
|
||||
$('#select-branch').val([[*{branchId}]]);
|
||||
$('#select-branch').selectpicker('refresh');
|
||||
|
||||
</script>
|
||||
</div>
|
||||
<div class="col-md-1 col-sm-12">
|
||||
Автор
|
||||
</div>
|
||||
<div class="col-md-3 col-sm-12">
|
||||
<select id="select-author" class="selectpicker" data-live-search="true" th:field="*{author}"
|
||||
data-width="90%">
|
||||
<option value="">Все авторы</option>
|
||||
<option th:each="author : ${authors}"
|
||||
th:value="${author}"
|
||||
th:utext="${author}">
|
||||
</option>
|
||||
</select>
|
||||
<script th:inline="javascript">
|
||||
$('#select-author').val([[*{author}]]);
|
||||
$('#select-author').selectpicker('refresh');
|
||||
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-2 col-sm-12">
|
||||
Искать по тексту:
|
||||
</div>
|
||||
<div class="col-md-3 col-sm-12">
|
||||
<input type="text" class="form-control" size="40" th:field="*{filter}">
|
||||
</div>
|
||||
<div class="col-md-3 col-sm-12">
|
||||
<div class="form-group form-check">
|
||||
<select id="select-entity-present" class="selectpicker" th:field="*{entity}"
|
||||
data-width="90%">
|
||||
<option value="">Не определено</option>
|
||||
<option th:each="ep : ${entityPresent}"
|
||||
th:value="${ep.value}"
|
||||
th:utext="${ep.key}">
|
||||
</option>
|
||||
</select>
|
||||
<script th:inline="javascript">
|
||||
$('select[name=selValue]').val([[*{entity}]]);
|
||||
$('#select-entity-present').selectpicker('refresh');
|
||||
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4 col-sm-12">
|
||||
<input type="submit" class="btn btn-outline-success w-100" value="Применить фильтр"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" th:field="*{branchId}">
|
||||
|
||||
<div class="row">
|
||||
<div id="container" style="width: 550px; height: 400px; margin: 0 auto"></div>
|
||||
<div id="containerPie" style="width: 550px; height: 400px; margin: 0 auto"></div>
|
||||
<div id="containerColumn" style="width: 550px; height: 400px; margin: 0 auto"></div>
|
||||
<div id="containerEntityPie" style="width: 550px; height: 400px; margin: 0 auto"></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</html>
|
||||
|
Loading…
Reference in New Issue
Block a user