Resolve "Индексировать репозиторий в БД" #40

Merged
romanov73 merged 1 commits from 16-indexing into master 2021-03-29 15:40:28 +04:00
11 changed files with 181 additions and 44 deletions

View File

@ -53,6 +53,7 @@ dependencies {
compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-hibernate5' compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-hibernate5'
compile group: 'org.postgresql', name: 'postgresql', version: '9.4.1212' compile group: 'org.postgresql', name: 'postgresql', version: '9.4.1212'
compile group: 'org.liquibase', name: 'liquibase-core', version: '4.3.1' compile group: 'org.liquibase', name: 'liquibase-core', version: '4.3.1'
implementation group: 'commons-io', name: 'commons-io', version: '2.6'
compile group: 'io.springfox', name: 'springfox-boot-starter', version: '3.0.0' compile group: 'io.springfox', name: 'springfox-boot-starter', version: '3.0.0'

View File

@ -1,22 +1,18 @@
package ru.ulstu.extractor.controller; package ru.ulstu.extractor.controller;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import ru.ulstu.extractor.model.Commit; import ru.ulstu.extractor.model.Commit;
import ru.ulstu.extractor.model.OffsetablePageRequest;
import ru.ulstu.extractor.model.mvc.FilterForm; import ru.ulstu.extractor.model.mvc.FilterForm;
import ru.ulstu.extractor.service.CommitService;
import ru.ulstu.extractor.service.FilteringService; import ru.ulstu.extractor.service.FilteringService;
import ru.ulstu.extractor.service.GitRepositoryService; import ru.ulstu.extractor.service.IndexService;
import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -25,18 +21,15 @@ import java.util.stream.IntStream;
@Controller @Controller
public class GitFilteringController { public class GitFilteringController {
private final FilteringService filteringService; private final FilteringService filteringService;
private final GitRepositoryService gitRepositoryService; private final IndexService indexService;
private final CommitService commitService;
public GitFilteringController(FilteringService filteringService, public GitFilteringController(FilteringService filteringService,
GitRepositoryService gitRepositoryService, IndexService indexService) {
CommitService commitService) {
this.filteringService = filteringService; this.filteringService = filteringService;
this.gitRepositoryService = gitRepositoryService; this.indexService = indexService;
this.commitService = commitService;
} }
@PostMapping("/sendFilter") /* @PostMapping("/sendFilter")
public String sendFilter(@ModelAttribute FilterForm filterForm, Model model) throws GitAPIException, IOException { public String sendFilter(@ModelAttribute FilterForm filterForm, Model model) throws GitAPIException, IOException {
List<Commit> list = gitRepositoryService.getCommits(filterForm.getUrl(), filterForm.getBranch()); List<Commit> list = gitRepositoryService.getCommits(filterForm.getUrl(), filterForm.getBranch());
model.addAttribute("commits", list); model.addAttribute("commits", list);
@ -45,7 +38,7 @@ public class GitFilteringController {
return "filtering"; return "filtering";
} }
return "resultRepo"; return "resultRepo";
} }*/
@RequestMapping(value = "/filtering", method = RequestMethod.GET) @RequestMapping(value = "/filtering", method = RequestMethod.GET)
public String listCommits( public String listCommits(
@ -54,18 +47,23 @@ public class GitFilteringController {
@RequestParam("page") Optional<Integer> page, @RequestParam("page") Optional<Integer> page,
@RequestParam("size") Optional<Integer> size, @RequestParam("size") Optional<Integer> size,
@RequestParam String repositoryUrl, @RequestParam String repositoryUrl,
@RequestParam String branchName) throws GitAPIException, IOException { @RequestParam String branchName) {
int currentPage = page.orElse(1); int currentPage = page.orElse(1);
int pageSize = size.orElse(5); int pageSize = size.orElse(5);
Page<Commit> commitPage = commitService.findPaginated(PageRequest.of(currentPage - 1, pageSize), repositoryUrl, branchName);
model.addAttribute("commitPage", commitPage); Page<Commit> commitsPage = indexService.getCommits(repositoryUrl, branchName, new OffsetablePageRequest(currentPage, pageSize));
int totalPages = commitPage.getTotalPages(); int totalPages = commitsPage.getTotalPages();
if (totalPages > 0) { if (totalPages > 0) {
List<Integer> pageNumbers = IntStream.rangeClosed(1, totalPages) List<Integer> pageNumbers = IntStream.rangeClosed(1, totalPages)
.boxed() .boxed()
.collect(Collectors.toList()); .collect(Collectors.toList());
model.addAttribute("pageNumbers", pageNumbers); model.addAttribute("pageNumbers", pageNumbers);
} }
filterForm = new FilterForm();
filterForm.setCommitsPage(commitsPage);
filterForm.setBranch(branchName);
filterForm.setUrl(repositoryUrl);
model.addAttribute("filterForm", filterForm);
return "filtering"; return "filtering";
} }
} }

View File

@ -24,6 +24,8 @@ public class Commit extends BaseEntity {
@JoinColumn(name = "commit_id", unique = true) @JoinColumn(name = "commit_id", unique = true)
@Fetch(FetchMode.SUBSELECT) @Fetch(FetchMode.SUBSELECT)
private List<FileChange> fileChanges = new ArrayList<>(); private List<FileChange> fileChanges = new ArrayList<>();
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Branch branch;
public Commit() { public Commit() {
} }
@ -74,4 +76,12 @@ public class Commit extends BaseEntity {
public Author getAuthor() { public Author getAuthor() {
return author; return author;
} }
public Branch getBranch() {
return branch;
}
public void setBranch(Branch branch) {
this.branch = branch;
}
} }

View File

@ -0,0 +1,93 @@
package ru.ulstu.extractor.model;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import java.io.Serializable;
public class OffsetablePageRequest implements Pageable, Serializable {
private final int offset;
private final int count;
private final Sort sort;
public OffsetablePageRequest(int page, long pageSize) {
this(pageSize * page, pageSize, Sort.by("id"));
}
public OffsetablePageRequest(long offset, long count, Sort sort) {
if (offset < 0) {
throw new IllegalArgumentException("Offset value must not be less than zero!");
}
if (count < 1) {
throw new IllegalArgumentException("Count value must not be less than one!");
}
this.offset = (int) offset;
this.count = (int) count;
this.sort = sort;
}
@Override
public Sort getSort() {
return sort;
}
@Override
public int getPageSize() {
return count;
}
@Override
public int getPageNumber() {
return offset / count;
}
@Override
public long getOffset() {
return offset;
}
@Override
public boolean hasPrevious() {
return offset > 0;
}
@Override
public Pageable next() {
return new OffsetablePageRequest(getOffset() + getPageSize(), getPageSize(), getSort());
}
@Override
public Pageable previousOrFirst() {
return hasPrevious() ? previous() : first();
}
public Pageable previous() {
return getOffset() == 0 ? this : new OffsetablePageRequest(getOffset() - getPageSize(), getPageSize(), getSort());
}
@Override
public Pageable first() {
return new OffsetablePageRequest(0, getPageSize(), getSort());
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
final OffsetablePageRequest other = (OffsetablePageRequest) obj;
return this.offset == other.offset && this.count == other.count;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + offset;
result = prime * result + count;
return result;
}
}

View File

@ -1,9 +1,13 @@
package ru.ulstu.extractor.model.mvc; package ru.ulstu.extractor.model.mvc;
import org.springframework.data.domain.Page;
import ru.ulstu.extractor.model.Commit;
public class FilterForm { public class FilterForm {
private String filter; private String filter;
private String url; private String url;
private String branch; private String branch;
private Page<Commit> commitsPage;
public FilterForm() { public FilterForm() {
} }
@ -36,6 +40,14 @@ public class FilterForm {
this.branch = branch; this.branch = branch;
} }
public Page<Commit> getCommitsPage() {
return commitsPage;
}
public void setCommitsPage(Page<Commit> commitsPage) {
this.commitsPage = commitsPage;
}
@Override @Override
public String toString() { public String toString() {
return "FilterForm{" + return "FilterForm{" +

View File

@ -0,0 +1,14 @@
package ru.ulstu.extractor.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import ru.ulstu.extractor.model.Author;
import ru.ulstu.extractor.model.Repository;
import java.util.List;
public interface AuthorRepository extends JpaRepository<Author, Integer> {
@Query("SELECT a 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")
List<Author> findByRepositoryAndBranch(@Param("repository") Repository repository, @Param("branchName") String branchName);
}

View File

@ -1,7 +1,14 @@
package ru.ulstu.extractor.repository; package ru.ulstu.extractor.repository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import ru.ulstu.extractor.model.Commit; import ru.ulstu.extractor.model.Commit;
import ru.ulstu.extractor.model.Repository;
public interface CommitRepository extends JpaRepository<Commit, Integer> { public interface CommitRepository extends JpaRepository<Commit, Integer> {
@Query("SELECT c FROM Commit c, Repository r, Branch b WHERE c.branch = b AND r = b.repository AND r = :repository AND b.name = :branchName")
Page<Commit> findByRepositoryAndBranch(Pageable pageable, @Param("repository") Repository repository, @Param("branchName") String branchName);
} }

View File

@ -1,32 +1,13 @@
package ru.ulstu.extractor.service; package ru.ulstu.extractor.service;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ru.ulstu.extractor.model.Commit;
import java.util.List;
import java.util.stream.Collectors;
@Service @Service
public class FilteringService { public class FilteringService {
private final GitRepositoryService gitRepositoryService; private final IndexService indexService;
public FilteringService(GitRepositoryService gitRepositoryService) { public FilteringService(IndexService indexService) {
this.gitRepositoryService = gitRepositoryService; this.indexService = indexService;
}
public List<Commit> getCommits(String urlRepo) {
return getCommits(urlRepo, null);
}
public List<Commit> getCommits(String urlRepo, String filterCommitMessage) {
if (filterCommitMessage != null) {
return getCommits(urlRepo)
.stream()
.filter(commit -> commit.getMessage().contains(filterCommitMessage))
.collect(Collectors.toList());
} else {
return getCommits(urlRepo);
}
} }
} }

View File

@ -213,4 +213,8 @@ public class GitRepositoryService {
.map(r -> new Branch(r.getName().replace(BRANCH_PREFIX, ""))) .map(r -> new Branch(r.getName().replace(BRANCH_PREFIX, "")))
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
public void remove(String repositoryUrl) throws IOException {
//FileUtils.deleteDirectory(getProjectDirectoryFile(repositoryUrl));
}
} }

View File

@ -2,10 +2,14 @@ package ru.ulstu.extractor.service;
import com.sun.istack.NotNull; import com.sun.istack.NotNull;
import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.GitAPIException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ru.ulstu.extractor.model.Author;
import ru.ulstu.extractor.model.Branch; import ru.ulstu.extractor.model.Branch;
import ru.ulstu.extractor.model.Commit; import ru.ulstu.extractor.model.Commit;
import ru.ulstu.extractor.model.Repository; import ru.ulstu.extractor.model.Repository;
import ru.ulstu.extractor.repository.AuthorRepository;
import ru.ulstu.extractor.repository.BranchRepository; import ru.ulstu.extractor.repository.BranchRepository;
import ru.ulstu.extractor.repository.CommitRepository; import ru.ulstu.extractor.repository.CommitRepository;
import ru.ulstu.extractor.repository.RepositoryRepository; import ru.ulstu.extractor.repository.RepositoryRepository;
@ -19,15 +23,19 @@ public class IndexService {
private final RepositoryRepository repositoryRepository; private final RepositoryRepository repositoryRepository;
private final BranchRepository branchRepository; private final BranchRepository branchRepository;
private final CommitRepository commitRepository; private final CommitRepository commitRepository;
private final AuthorRepository authorRepository;
public IndexService(GitRepositoryService gitRepositoryService, public IndexService(GitRepositoryService gitRepositoryService,
RepositoryRepository repositoryRepository, RepositoryRepository repositoryRepository,
BranchRepository branchRepository, BranchRepository branchRepository,
CommitRepository commitRepository) { CommitRepository commitRepository,
AuthorRepository authorRepository) {
this.gitRepositoryService = gitRepositoryService; this.gitRepositoryService = gitRepositoryService;
this.repositoryRepository = repositoryRepository; this.repositoryRepository = repositoryRepository;
this.branchRepository = branchRepository; this.branchRepository = branchRepository;
this.commitRepository = commitRepository; this.commitRepository = commitRepository;
this.authorRepository = authorRepository;
} }
public void index(@NotNull String repositoryUrl, @NotNull String branchName) throws GitAPIException, IOException { public void index(@NotNull String repositoryUrl, @NotNull String branchName) throws GitAPIException, IOException {
@ -42,5 +50,14 @@ public class IndexService {
List<Commit> commits = gitRepositoryService.getCommits(repositoryUrl, branchName); List<Commit> commits = gitRepositoryService.getCommits(repositoryUrl, branchName);
branch.setCommits(commits); branch.setCommits(commits);
branchRepository.save(branch); branchRepository.save(branch);
gitRepositoryService.remove(repositoryUrl);
}
public List<Author> getRepositoryAuthors(@NotNull String repositoryUrl, @NotNull String branchName) {
return authorRepository.findByRepositoryAndBranch(repositoryRepository.findByUrl(repositoryUrl), branchName);
}
public Page<Commit> getCommits(@NotNull String repositoryUrl, @NotNull String branchName, Pageable pageable) {
return commitRepository.findByRepositoryAndBranch(pageable, repositoryRepository.findByUrl(repositoryUrl), branchName);
} }
} }

View File

@ -38,8 +38,8 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr th:each="commit: ${commits}"> <tr th:each="commit: ${filterForm.commitsPage.content}">
<td th:text="${commit.author}"></td> <td th:text="${commit.author.name}"></td>
<td th:text="${commit.date}"></td> <td th:text="${commit.date}"></td>
<td th:text="${commit.message}"></td> <td th:text="${commit.message}"></td>
</tr> </tr>
@ -50,7 +50,7 @@
</p> </p>
</form> </form>
</div> </div>
<div th:if="${commitPage.totalPages > 0}" class="pagination" <div th:if="${filterForm.commitPage.totalPages > 0}" class="pagination"
th:each="pageNumber : ${pageNumbers}"> th:each="pageNumber : ${pageNumbers}">
<a th:href="@{/filtering.html(size=${commitPage.size}, page=${pageNumber})}" <a th:href="@{/filtering.html(size=${commitPage.size}, page=${pageNumber})}"
th:class="${pageNumber==commitPage.number + 1} ? active"></a> th:class="${pageNumber==commitPage.number + 1} ? active"></a>