Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Development: Improve JPQL style for programming repositories #7975

Merged
merged 10 commits into from
Feb 13, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,21 @@
public interface BuildLogStatisticsEntryRepository extends JpaRepository<BuildLogStatisticsEntry, Long> {

@Query("""
SELECT new de.tum.in.www1.artemis.web.rest.dto.BuildLogStatisticsDTO(count(b.id), avg(b.agentSetupDuration), avg(b.testDuration), avg(b.scaDuration), avg(b.totalJobDuration), avg(b.dependenciesDownloadedCount))
FROM BuildLogStatisticsEntry b, Submission s, Participation p
WHERE b.programmingSubmission = s
AND s.participation = p
AND (
p.exercise = :#{#exercise}
OR :#{#exercise.solutionParticipation != null ? #exercise.solutionParticipation.id : #exercise.solutionParticipation} = p.id
OR :#{#exercise.templateParticipation != null ? #exercise.templateParticipation.id : #exercise.templateParticipation} = p.id
)
SELECT new de.tum.in.www1.artemis.web.rest.dto.BuildLogStatisticsDTO(
COUNT(b.id),
AVG(b.agentSetupDuration),
AVG(b.testDuration),
AVG(b.scaDuration),
AVG(b.totalJobDuration),
AVG(b.dependenciesDownloadedCount)
)
FROM BuildLogStatisticsEntry b
LEFT JOIN b.programmingSubmission s
LEFT JOIN s.participation p
LEFT JOIN TREAT (p.exercise as ProgrammingExercise ) e
WHERE e = :exercise
OR e.solutionParticipation = p
OR e.templateParticipation = p
""")
BuildLogStatisticsDTO findAverageBuildLogStatisticsEntryForExercise(@Param("exercise") ProgrammingExercise exercise);

Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -37,58 +37,58 @@ public interface ProgrammingExerciseStudentParticipationRepository extends JpaRe
LEFT JOIN FETCH pr.submission
WHERE p.id = :participationId
AND (pr.id = (
SELECT max(prr.id)
SELECT MAX(prr.id)
FROM p.results prr
WHERE (prr.assessmentType = 'AUTOMATIC'
WHERE (prr.assessmentType = de.tum.in.www1.artemis.domain.enumeration.AssessmentType.AUTOMATIC
OR (prr.completionDate IS NOT NULL
AND (p.exercise.assessmentDueDate IS NULL
OR p.exercise.assessmentDueDate < :#{#dateTime}))))
OR pr.id IS NULL)
AND (p.exercise.assessmentDueDate IS NULL OR p.exercise.assessmentDueDate < :dateTime)
)
)
) OR pr.id IS NULL)
""")
Optional<ProgrammingExerciseStudentParticipation> findByIdWithLatestResultAndFeedbacksAndRelatedSubmissions(@Param("participationId") Long participationId,
Optional<ProgrammingExerciseStudentParticipation> findByIdWithLatestResultAndFeedbacksAndRelatedSubmissions(@Param("participationId") long participationId,
@Param("dateTime") ZonedDateTime dateTime);

@EntityGraph(type = LOAD, attributePaths = { "results", "exercise", "team.students" })
List<ProgrammingExerciseStudentParticipation> findWithResultsAndExerciseAndTeamStudentsByBuildPlanId(String buildPlanId);

@Query("""
SELECT DISTINCT p
FROM ProgrammingExerciseStudentParticipation p
LEFT JOIN FETCH p.results
WHERE p.buildPlanId IS NOT NULL
AND (p.student IS NOT NULL
OR p.team IS NOT NULL)
SELECT DISTINCT p
FROM ProgrammingExerciseStudentParticipation p
LEFT JOIN FETCH p.results
WHERE p.buildPlanId IS NOT NULL
AND (p.student IS NOT NULL OR p.team IS NOT NULL)
""")
List<ProgrammingExerciseStudentParticipation> findAllWithBuildPlanIdWithResults();

Optional<ProgrammingExerciseStudentParticipation> findByExerciseIdAndStudentLogin(Long exerciseId, String username);
Optional<ProgrammingExerciseStudentParticipation> findByExerciseIdAndStudentLogin(long exerciseId, String username);

default ProgrammingExerciseStudentParticipation findByExerciseIdAndStudentLoginOrThrow(Long exerciseId, String username) {
default ProgrammingExerciseStudentParticipation findByExerciseIdAndStudentLoginOrThrow(long exerciseId, String username) {
return findByExerciseIdAndStudentLogin(exerciseId, username).orElseThrow(() -> new EntityNotFoundException("Programming Exercise Student Participation", exerciseId));
}

@EntityGraph(type = LOAD, attributePaths = { "submissions" })
Optional<ProgrammingExerciseStudentParticipation> findWithSubmissionsByExerciseIdAndStudentLogin(Long exerciseId, String username);
Optional<ProgrammingExerciseStudentParticipation> findWithSubmissionsByExerciseIdAndStudentLogin(long exerciseId, String username);

default ProgrammingExerciseStudentParticipation findWithSubmissionsByExerciseIdAndStudentLoginOrThrow(Long exerciseId, String username) {
default ProgrammingExerciseStudentParticipation findWithSubmissionsByExerciseIdAndStudentLoginOrThrow(long exerciseId, String username) {
return findWithSubmissionsByExerciseIdAndStudentLogin(exerciseId, username)
.orElseThrow(() -> new EntityNotFoundException("Programming Exercise Student Participation", exerciseId));
}

Optional<ProgrammingExerciseStudentParticipation> findByExerciseIdAndStudentLoginAndTestRun(Long exerciseId, String username, boolean testRun);
Optional<ProgrammingExerciseStudentParticipation> findByExerciseIdAndStudentLoginAndTestRun(long exerciseId, String username, boolean testRun);

@EntityGraph(type = LOAD, attributePaths = { "team" })
Optional<ProgrammingExerciseStudentParticipation> findByExerciseIdAndTeamId(Long exerciseId, Long teamId);
Optional<ProgrammingExerciseStudentParticipation> findByExerciseIdAndTeamId(long exerciseId, long teamId);

@Query("""
SELECT DISTINCT participation
FROM ProgrammingExerciseStudentParticipation participation
LEFT JOIN FETCH participation.team team
LEFT JOIN FETCH team.students
WHERE participation.exercise.id = :#{#exerciseId}
AND participation.team.shortName = :#{#teamShortName}
WHERE participation.exercise.id = :exerciseId
AND participation.team.shortName = :teamShortName
""")
Optional<ProgrammingExerciseStudentParticipation> findWithEagerStudentsByExerciseIdAndTeamShortName(@Param("exerciseId") Long exerciseId,
Optional<ProgrammingExerciseStudentParticipation> findWithEagerStudentsByExerciseIdAndTeamShortName(@Param("exerciseId") long exerciseId,
@Param("teamShortName") String teamShortName);

@Query("""
Expand All @@ -97,22 +97,22 @@ Optional<ProgrammingExerciseStudentParticipation> findWithEagerStudentsByExercis
LEFT JOIN FETCH participation.submissions
LEFT JOIN FETCH participation.team team
LEFT JOIN FETCH team.students
WHERE participation.exercise.id = :#{#exerciseId}
AND participation.team.shortName = :#{#teamShortName}
WHERE participation.exercise.id = :exerciseId
AND participation.team.shortName = :teamShortName
""")
Optional<ProgrammingExerciseStudentParticipation> findWithSubmissionsAndEagerStudentsByExerciseIdAndTeamShortName(@Param("exerciseId") Long exerciseId,
Optional<ProgrammingExerciseStudentParticipation> findWithSubmissionsAndEagerStudentsByExerciseIdAndTeamShortName(@Param("exerciseId") long exerciseId,
@Param("teamShortName") String teamShortName);

List<ProgrammingExerciseStudentParticipation> findByExerciseId(Long exerciseId);
List<ProgrammingExerciseStudentParticipation> findByExerciseId(long exerciseId);

@EntityGraph(type = LOAD, attributePaths = { "submissions" })
List<ProgrammingExerciseStudentParticipation> findWithSubmissionsById(long participationId);

@EntityGraph(type = LOAD, attributePaths = { "submissions" })
List<ProgrammingExerciseStudentParticipation> findWithSubmissionsByExerciseId(Long exerciseId);
List<ProgrammingExerciseStudentParticipation> findWithSubmissionsByExerciseId(long exerciseId);

@EntityGraph(type = LOAD, attributePaths = { "submissions", "team.students" })
List<ProgrammingExerciseStudentParticipation> findWithSubmissionsAndTeamStudentsByExerciseId(Long exerciseId);
List<ProgrammingExerciseStudentParticipation> findWithSubmissionsAndTeamStudentsByExerciseId(long exerciseId);

/**
* Will return the participations matching the provided participation ids, but only if they belong to the given exercise.
Expand All @@ -125,72 +125,73 @@ Optional<ProgrammingExerciseStudentParticipation> findWithSubmissionsAndEagerStu
SELECT participation
FROM ProgrammingExerciseStudentParticipation participation
LEFT JOIN FETCH participation.submissions
WHERE participation.exercise.id = :#{#exerciseId}
AND participation.id IN :#{#participationIds}
WHERE participation.exercise.id = :exerciseId
AND participation.id IN :participationIds
""")
List<ProgrammingExerciseStudentParticipation> findWithSubmissionsByExerciseIdAndParticipationIds(@Param("exerciseId") Long exerciseId,
List<ProgrammingExerciseStudentParticipation> findWithSubmissionsByExerciseIdAndParticipationIds(@Param("exerciseId") long exerciseId,
@Param("participationIds") Collection<Long> participationIds);

@Query("""
SELECT participation
FROM ProgrammingExerciseStudentParticipation participation
LEFT JOIN FETCH participation.submissions
WHERE participation.exercise.id = :#{#exerciseId}
AND participation.student.login = :#{#username}
AND participation.testRun = :#{#testRun}
WHERE participation.exercise.id = :exerciseId
AND participation.student.login = :username
AND participation.testRun = :testRun
""")
Optional<ProgrammingExerciseStudentParticipation> findWithSubmissionsByExerciseIdAndStudentLoginAndTestRun(@Param("exerciseId") Long exerciseId,
Optional<ProgrammingExerciseStudentParticipation> findWithSubmissionsByExerciseIdAndStudentLoginAndTestRun(@Param("exerciseId") long exerciseId,
@Param("username") String username, @Param("testRun") boolean testRun);

@Query("""
SELECT participation
FROM ProgrammingExerciseStudentParticipation participation
LEFT JOIN FETCH participation.submissions
WHERE participation.exercise.id = :#{#exerciseId}
AND participation.student.login = :#{#username}
WHERE participation.exercise.id = :exerciseId
AND participation.student.login = :username
ORDER BY participation.testRun ASC
""")
List<ProgrammingExerciseStudentParticipation> findAllWithSubmissionsByExerciseIdAndStudentLogin(@Param("exerciseId") Long exerciseId, @Param("username") String username);
List<ProgrammingExerciseStudentParticipation> findAllWithSubmissionsByExerciseIdAndStudentLogin(@Param("exerciseId") long exerciseId, @Param("username") String username);

@EntityGraph(type = LOAD, attributePaths = "student")
Optional<ProgrammingExerciseStudentParticipation> findWithStudentById(Long participationId);
Optional<ProgrammingExerciseStudentParticipation> findWithStudentById(long participationId);

@EntityGraph(type = LOAD, attributePaths = "team.students")
Optional<ProgrammingExerciseStudentParticipation> findWithTeamStudentsById(Long participationId);
Optional<ProgrammingExerciseStudentParticipation> findWithTeamStudentsById(long participationId);

@NotNull
default ProgrammingExerciseStudentParticipation findByIdElseThrow(Long participationId) {
default ProgrammingExerciseStudentParticipation findByIdElseThrow(long participationId) {
return findById(participationId).orElseThrow(() -> new EntityNotFoundException("Programming Exercise Student Participation", participationId));
}

default Optional<ProgrammingExerciseStudentParticipation> findStudentParticipationWithLatestResultAndFeedbacksAndRelatedSubmissions(Long participationId) {
default Optional<ProgrammingExerciseStudentParticipation> findStudentParticipationWithLatestResultAndFeedbacksAndRelatedSubmissions(long participationId) {
return findByIdWithLatestResultAndFeedbacksAndRelatedSubmissions(participationId, ZonedDateTime.now());
}

default ProgrammingExerciseStudentParticipation findWithTeamStudentsByIdElseThrow(Long participationId) {
default ProgrammingExerciseStudentParticipation findWithTeamStudentsByIdElseThrow(long participationId) {
return findWithTeamStudentsById(participationId).orElseThrow(() -> new EntityNotFoundException("Programming Exercise Student Participation", participationId));
}

@Transactional // ok because of modifying query
@Modifying
@Query("""
UPDATE ProgrammingExerciseStudentParticipation p
SET p.locked = :#{#locked}
WHERE p.id = :#{#participationId}
SET p.locked = :locked
WHERE p.id = :participationId
""")
void updateLockedById(@Param("participationId") Long participationId, @Param("locked") boolean locked);
void updateLockedById(@Param("participationId") long participationId, @Param("locked") boolean locked);

@Query("""
SELECT DISTINCT p
FROM ProgrammingExerciseStudentParticipation p
WHERE p.buildPlanId IS NOT NULL
WHERE p.buildPlanId IS NOT NULL
""")
Page<ProgrammingExerciseStudentParticipation> findAllWithBuildPlanId(Pageable pageable);

@Query("""
SELECT DISTINCT p
FROM ProgrammingExerciseStudentParticipation p
WHERE p.buildPlanId IS NOT NULL or p.repositoryUri IS NOT NULL
WHERE p.buildPlanId IS NOT NULL
OR p.repositoryUri IS NOT NULL
""")
Page<ProgrammingExerciseStudentParticipation> findAllWithRepositoryUriOrBuildPlanId(Pageable pageable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
@Repository
public interface ProgrammingExerciseTestCaseRepository extends JpaRepository<ProgrammingExerciseTestCase, Long> {

Set<ProgrammingExerciseTestCase> findByExerciseId(Long exerciseId);
Set<ProgrammingExerciseTestCase> findByExerciseId(long exerciseId);

Optional<ProgrammingExerciseTestCase> findByExerciseIdAndTestName(Long exerciseId, String testName);
Optional<ProgrammingExerciseTestCase> findByExerciseIdAndTestName(long exerciseId, String testName);

default ProgrammingExerciseTestCase findByIdWithExerciseElseThrow(Long testCaseId) {
default ProgrammingExerciseTestCase findByIdWithExerciseElseThrow(long testCaseId) {
return findByIdWithExercise(testCaseId).orElseThrow(() -> new EntityNotFoundException("Programming Exercise Test Case", testCaseId));
}

Expand All @@ -37,7 +37,7 @@ default ProgrammingExerciseTestCase findByIdWithExerciseElseThrow(Long testCaseI
LEFT JOIN FETCH tc.exercise ex
WHERE tc.id = :testCaseId
""")
Optional<ProgrammingExerciseTestCase> findByIdWithExercise(@Param("testCaseId") Long testCaseId);
Optional<ProgrammingExerciseTestCase> findByIdWithExercise(@Param("testCaseId") long testCaseId);

/**
* Returns all test cases with the associated solution entries for a programming exercise
Expand All @@ -51,7 +51,7 @@ default ProgrammingExerciseTestCase findByIdWithExerciseElseThrow(Long testCaseI
LEFT JOIN FETCH tc.solutionEntries se
WHERE tc.exercise.id = :exerciseId
""")
Set<ProgrammingExerciseTestCase> findByExerciseIdWithSolutionEntries(@Param("exerciseId") Long exerciseId);
Set<ProgrammingExerciseTestCase> findByExerciseIdWithSolutionEntries(@Param("exerciseId") long exerciseId);

/**
* Returns all test cases with the associated solution entries for a programming exercise
Expand All @@ -61,14 +61,15 @@ default ProgrammingExerciseTestCase findByIdWithExerciseElseThrow(Long testCaseI
* @return all test cases with the associated solution entries
*/
@Query("""
SELECT DISTINCT tc FROM ProgrammingExerciseTestCase tc
SELECT DISTINCT tc
FROM ProgrammingExerciseTestCase tc
LEFT JOIN FETCH tc.solutionEntries se
WHERE tc.exercise.id = :exerciseId
AND tc.active = :active
""")
Set<ProgrammingExerciseTestCase> findByExerciseIdWithSolutionEntriesAndActive(@Param("exerciseId") Long exerciseId, @Param("active") Boolean active);
Set<ProgrammingExerciseTestCase> findByExerciseIdWithSolutionEntriesAndActive(@Param("exerciseId") long exerciseId, @Param("active") Boolean active);

Set<ProgrammingExerciseTestCase> findByExerciseIdAndActive(Long exerciseId, Boolean active);
Set<ProgrammingExerciseTestCase> findByExerciseIdAndActive(long exerciseId, Boolean active);

/**
* Returns the number of test cases marked as {@link de.tum.in.www1.artemis.domain.enumeration.Visibility#AFTER_DUE_DATE} for the given exercise.
Expand All @@ -77,10 +78,10 @@ default ProgrammingExerciseTestCase findByIdWithExerciseElseThrow(Long testCaseI
* @return the number of test cases marked as {@link de.tum.in.www1.artemis.domain.enumeration.Visibility#AFTER_DUE_DATE}.
*/
@Query("""
SELECT count(DISTINCT testCase)
SELECT COUNT(DISTINCT testCase)
FROM ProgrammingExerciseTestCase testCase
WHERE testCase.exercise.id = :exerciseId
AND testCase.visibility = 'AFTER_DUE_DATE'
AND testCase.visibility = de.tum.in.www1.artemis.domain.enumeration.Visibility.AFTER_DUE_DATE
""")
long countAfterDueDateByExerciseId(@Param("exerciseId") Long exerciseId);
long countAfterDueDateByExerciseId(@Param("exerciseId") long exerciseId);
}
Loading
Loading