diff --git a/judgels-backends/judgels-server-app/src/main/java/judgels/JudgelsServerApplication.java b/judgels-backends/judgels-server-app/src/main/java/judgels/JudgelsServerApplication.java index 906231cf7..64c96ebf0 100644 --- a/judgels-backends/judgels-server-app/src/main/java/judgels/JudgelsServerApplication.java +++ b/judgels-backends/judgels-server-app/src/main/java/judgels/JudgelsServerApplication.java @@ -270,6 +270,7 @@ private void runJerahmeel(JudgelsServerApplicationConfiguration config, Environm component.gradingResponsePoller()); } + env.admin().addTask(component.deleteProblemTask()); env.admin().addTask(component.moveProblemToChapterTask()); env.admin().addTask(component.problemSetStatsTask()); env.admin().addTask(component.contestStatsTask()); diff --git a/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/JerahmeelComponent.java b/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/JerahmeelComponent.java index 47cf02f55..180c7210a 100755 --- a/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/JerahmeelComponent.java +++ b/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/JerahmeelComponent.java @@ -12,6 +12,7 @@ import judgels.jerahmeel.course.chapter.CourseChapterResource; import judgels.jerahmeel.curriculum.CurriculumResource; import judgels.jerahmeel.hibernate.JerahmeelHibernateDaoModule; +import judgels.jerahmeel.problem.DeleteProblemTask; import judgels.jerahmeel.problem.MoveProblemToChapterTask; import judgels.jerahmeel.problem.ProblemModule; import judgels.jerahmeel.problem.ProblemResource; @@ -86,6 +87,7 @@ public interface JerahmeelComponent { JudgelsScheduler scheduler(); GradingResponsePoller gradingResponsePoller(); + DeleteProblemTask deleteProblemTask(); MoveProblemToChapterTask moveProblemToChapterTask(); ProblemSetStatsTask problemSetStatsTask(); ContestStatsTask contestStatsTask(); diff --git a/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/hibernate/ProgrammingGradingHibernateDao.java b/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/hibernate/ProgrammingGradingHibernateDao.java index bdff1f656..28481b753 100644 --- a/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/hibernate/ProgrammingGradingHibernateDao.java +++ b/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/hibernate/ProgrammingGradingHibernateDao.java @@ -5,6 +5,7 @@ import judgels.jerahmeel.persistence.ProgrammingGradingModel; import judgels.persistence.hibernate.HibernateDaoData; import judgels.sandalphon.hibernate.AbstractProgrammingGradingHibernateDao; +import org.hibernate.query.Query; public class ProgrammingGradingHibernateDao extends AbstractProgrammingGradingHibernateDao< ProgrammingGradingModel> implements ProgrammingGradingDao { @@ -23,4 +24,15 @@ public ProgrammingGradingModel createGradingModel() { public Class getGradingModelClass() { return ProgrammingGradingModel.class; } + + @Override + public void deleteAllByProblemJid(String problemJid) { + Query query = currentSession().createQuery( + "DELETE FROM jerahmeel_programming_grading " + + "WHERE submissionJid IN (" + + "SELECT jid FROM jerahmeel_programming_submission WHERE problemJid = :problemJid) "); + + query.setParameter("problemJid", problemJid); + query.executeUpdate(); + } } diff --git a/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/hibernate/ProgrammingSubmissionHibernateDao.java b/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/hibernate/ProgrammingSubmissionHibernateDao.java index 40fa12dd2..4d186f54a 100644 --- a/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/hibernate/ProgrammingSubmissionHibernateDao.java +++ b/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/hibernate/ProgrammingSubmissionHibernateDao.java @@ -22,8 +22,8 @@ public ProgrammingSubmissionModel createSubmissionModel() { } @Override - public void updateContainer(String problemJid, String containerJid) { - Query query = currentSession().createQuery( + public void updateContainerJid(String problemJid, String containerJid) { + Query query = currentSession().createQuery( "UPDATE jerahmeel_programming_submission " + "SET containerJid = :containerJid " + "WHERE problemJid = :problemJid"); @@ -32,4 +32,14 @@ public void updateContainer(String problemJid, String containerJid) { query.setParameter("problemJid", problemJid); query.executeUpdate(); } + + @Override + public void deleteAllByProblemJid(String problemJid) { + Query query = currentSession().createQuery( + "DELETE FROM jerahmeel_programming_submission " + + "WHERE problemJid = :problemJid"); + + query.setParameter("problemJid", problemJid); + query.executeUpdate(); + } } diff --git a/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/hibernate/StatsUserProblemHibernateDao.java b/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/hibernate/StatsUserProblemHibernateDao.java index b791db1b9..73293f99b 100644 --- a/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/hibernate/StatsUserProblemHibernateDao.java +++ b/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/hibernate/StatsUserProblemHibernateDao.java @@ -19,6 +19,7 @@ import judgels.persistence.QueryBuilder; import judgels.persistence.hibernate.HibernateDao; import judgels.persistence.hibernate.HibernateDaoData; +import org.hibernate.query.Query; public class StatsUserProblemHibernateDao extends HibernateDao implements StatsUserProblemDao { private final Clock clock; @@ -193,4 +194,14 @@ public Map selectCountsVerdictByUserJid(String userJid) { .stream() .collect(Collectors.toMap(tuple -> tuple.get(0, String.class), tuple -> tuple.get(1, Long.class))); } + + @Override + public void deleteAllByProblemJid(String problemJid) { + Query query = currentSession().createQuery( + "DELETE FROM jerahmeel_stats_user_problem " + + "WHERE problemJid = :problemJid"); + + query.setParameter("problemJid", problemJid); + query.executeUpdate(); + } } diff --git a/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/persistence/StatsUserProblemDao.java b/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/persistence/StatsUserProblemDao.java index 0afa152fc..a8e4b956c 100644 --- a/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/persistence/StatsUserProblemDao.java +++ b/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/persistence/StatsUserProblemDao.java @@ -19,4 +19,5 @@ public interface StatsUserProblemDao extends Dao { long selectCountTriedByUserJid(String userJid); int selectTotalScoreByUserJid(String userJid); Map selectCountsVerdictByUserJid(String userJid); + void deleteAllByProblemJid(String problemJid); } diff --git a/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/problem/DeleteProblemTask.java b/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/problem/DeleteProblemTask.java new file mode 100644 index 000000000..d04f7e0bc --- /dev/null +++ b/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/problem/DeleteProblemTask.java @@ -0,0 +1,64 @@ +package judgels.jerahmeel.problem; + +import io.dropwizard.hibernate.UnitOfWork; +import io.dropwizard.servlets.tasks.Task; +import java.io.PrintWriter; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import judgels.jerahmeel.persistence.ChapterProblemDao; +import judgels.jerahmeel.persistence.ProblemSetProblemDao; +import judgels.jerahmeel.persistence.ProgrammingGradingDao; +import judgels.jerahmeel.persistence.ProgrammingSubmissionDao; +import judgels.jerahmeel.persistence.StatsUserProblemDao; +import judgels.sandalphon.persistence.ProblemDao; +import judgels.sandalphon.persistence.ProblemModel; + +public class DeleteProblemTask extends Task { + private final ProblemDao problemDao; + private final ChapterProblemDao chapterProblemDao; + private final ProblemSetProblemDao problemSetProblemDao; + private final ProgrammingSubmissionDao programmingSubmissionDao; + private final ProgrammingGradingDao programmingGradingDao; + private final StatsUserProblemDao statsUserProblemDao; + + public DeleteProblemTask( + ProblemDao problemDao, + ChapterProblemDao chapterProblemDao, + ProblemSetProblemDao problemSetProblemDao, + ProgrammingSubmissionDao programmingSubmissionDao, + ProgrammingGradingDao programmingGradingDao, + StatsUserProblemDao statsUserProblemDao) { + + super("jerahmeel-delete-problem"); + + this.problemDao = problemDao; + this.chapterProblemDao = chapterProblemDao; + this.problemSetProblemDao = problemSetProblemDao; + this.programmingSubmissionDao = programmingSubmissionDao; + this.programmingGradingDao = programmingGradingDao; + this.statsUserProblemDao = statsUserProblemDao; + } + + @Override + @UnitOfWork + public void execute(Map> parameters, PrintWriter out) { + List problemSlugs = parameters.get("problemSlug"); + if (problemSlugs == null || problemSlugs.isEmpty()) { + return; + } + String problemSlug = problemSlugs.get(0); + + Optional maybeProblemModel = problemDao.selectBySlug(problemSlug); + if (maybeProblemModel.isEmpty()) { + return; + } + String problemJid = maybeProblemModel.get().jid; + + statsUserProblemDao.deleteAllByProblemJid(problemJid); + programmingGradingDao.deleteAllByProblemJid(problemJid); + programmingSubmissionDao.deleteAllByProblemJid(problemJid); + chapterProblemDao.selectByProblemJid(problemJid).ifPresent(chapterProblemDao::delete); + problemSetProblemDao.selectAllByProblemJid(problemJid).forEach(problemSetProblemDao::delete); + } +} diff --git a/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/problem/MoveProblemToChapterTask.java b/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/problem/MoveProblemToChapterTask.java index ce41b592d..04f7db129 100644 --- a/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/problem/MoveProblemToChapterTask.java +++ b/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/problem/MoveProblemToChapterTask.java @@ -91,6 +91,6 @@ public void execute(Map> parameters, PrintWriter out) { List problemSetProblemModels = problemSetProblemDao.selectAllByProblemJid(problemJid); problemSetProblemModels.forEach(problemSetProblemDao::delete); - programmingSubmissionDao.updateContainer(problemJid, toChapterJid); + programmingSubmissionDao.updateContainerJid(problemJid, toChapterJid); } } diff --git a/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/problem/ProblemModule.java b/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/problem/ProblemModule.java index 6ec7f2956..4a48ebbfe 100644 --- a/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/problem/ProblemModule.java +++ b/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/problem/ProblemModule.java @@ -7,13 +7,44 @@ import judgels.jerahmeel.persistence.ChapterDao; import judgels.jerahmeel.persistence.ChapterProblemDao; import judgels.jerahmeel.persistence.ProblemSetProblemDao; +import judgels.jerahmeel.persistence.ProgrammingGradingDao; import judgels.jerahmeel.persistence.ProgrammingSubmissionDao; +import judgels.jerahmeel.persistence.StatsUserProblemDao; import judgels.sandalphon.persistence.ProblemDao; @Module public class ProblemModule { private ProblemModule() {} + @Provides + @Singleton + static DeleteProblemTask deleteProblemTask( + UnitOfWorkAwareProxyFactory unitOfWorkAwareProxyFactory, + ProblemDao problemDao, + ChapterProblemDao chapterProblemDao, + ProblemSetProblemDao problemSetProblemDao, + ProgrammingSubmissionDao programmingSubmissionDao, + ProgrammingGradingDao programmingGradingDao, + StatsUserProblemDao statsUserProblemDao) { + + return unitOfWorkAwareProxyFactory.create( + DeleteProblemTask.class, + new Class[] { + ProblemDao.class, + ChapterProblemDao.class, + ProblemSetProblemDao.class, + ProgrammingSubmissionDao.class, + ProgrammingGradingDao.class, + StatsUserProblemDao.class}, + new Object[] { + problemDao, + chapterProblemDao, + problemSetProblemDao, + programmingSubmissionDao, + programmingGradingDao, + statsUserProblemDao}); + } + @Provides @Singleton static MoveProblemToChapterTask problemMoveToChapterTask( diff --git a/judgels-backends/judgels-server-app/src/main/java/judgels/sandalphon/hibernate/AbstractProgrammingGradingHibernateDao.java b/judgels-backends/judgels-server-app/src/main/java/judgels/sandalphon/hibernate/AbstractProgrammingGradingHibernateDao.java index 3af54dcd8..41df0d9c9 100644 --- a/judgels-backends/judgels-server-app/src/main/java/judgels/sandalphon/hibernate/AbstractProgrammingGradingHibernateDao.java +++ b/judgels-backends/judgels-server-app/src/main/java/judgels/sandalphon/hibernate/AbstractProgrammingGradingHibernateDao.java @@ -91,30 +91,13 @@ public Map selectAllLatestWithDetailsBySubmissionJids(Collection submissionJids) { - List results = select().where(columnIn(AbstractProgrammingGradingModel_.submissionJid, submissionJids)).orderBy(Model_.ID, OrderDir.ASC).all(); - if (results.isEmpty()) { - return; - } + public void deleteAllByProblemJid(String problemJid) { + throw new UnsupportedOperationException(); + } - output.write("INSERT IGNORE INTO uriel_contest_programming_grading (jid, submissionJid, verdictCode, verdictName, score, details, createdBy, createdAt, updatedAt) VALUES\n"); - - for (int i = 0; i < results.size(); i++) { - M m = results.get(i); - if (i > 0) { - output.write(",\n"); - } - output.write(String.format("(%s, %s, %s, %s, %s, %s, %s, %s, %s)", - escape(m.jid), - escape(m.submissionJid), - escape(m.verdictCode), - escape(""), - escape(m.score), - escape(m.details), - escape(m.createdBy), - escape(m.createdAt), - escape(m.updatedAt))); - } - output.write(";\n"); + + @Override + public void dump(PrintWriter output, Collection submissionJids) { + throw new UnsupportedOperationException(); } } diff --git a/judgels-backends/judgels-server-app/src/main/java/judgels/sandalphon/hibernate/AbstractProgrammingSubmissionHibernateDao.java b/judgels-backends/judgels-server-app/src/main/java/judgels/sandalphon/hibernate/AbstractProgrammingSubmissionHibernateDao.java index 87cd82228..f9acd9e1b 100644 --- a/judgels-backends/judgels-server-app/src/main/java/judgels/sandalphon/hibernate/AbstractProgrammingSubmissionHibernateDao.java +++ b/judgels-backends/judgels-server-app/src/main/java/judgels/sandalphon/hibernate/AbstractProgrammingSubmissionHibernateDao.java @@ -63,7 +63,12 @@ public Map selectCounts(String containerJid, String userJid, Colle } @Override - public void updateContainer(String problemJid, String containerJid) { + public void updateContainerJid(String problemJid, String containerJid) { + throw new UnsupportedOperationException(); + } + + @Override + public void deleteAllByProblemJid(String problemJid) { throw new UnsupportedOperationException(); } diff --git a/judgels-backends/judgels-server-app/src/main/java/judgels/sandalphon/persistence/BaseProgrammingGradingDao.java b/judgels-backends/judgels-server-app/src/main/java/judgels/sandalphon/persistence/BaseProgrammingGradingDao.java index 0b109f1ad..bff7d186d 100644 --- a/judgels-backends/judgels-server-app/src/main/java/judgels/sandalphon/persistence/BaseProgrammingGradingDao.java +++ b/judgels-backends/judgels-server-app/src/main/java/judgels/sandalphon/persistence/BaseProgrammingGradingDao.java @@ -12,5 +12,6 @@ public interface BaseProgrammingGradingDao selectLatestBySubmissionJid(String submissionJid); Map selectAllLatestBySubmissionJids(Collection submissionJids); Map selectAllLatestWithDetailsBySubmissionJids(Collection submissionJids); + void deleteAllByProblemJid(String problemJid); void dump(PrintWriter output, Collection submissionJids); } diff --git a/judgels-backends/judgels-server-app/src/main/java/judgels/sandalphon/persistence/BaseProgrammingSubmissionDao.java b/judgels-backends/judgels-server-app/src/main/java/judgels/sandalphon/persistence/BaseProgrammingSubmissionDao.java index d90c276af..4df251d3e 100644 --- a/judgels-backends/judgels-server-app/src/main/java/judgels/sandalphon/persistence/BaseProgrammingSubmissionDao.java +++ b/judgels-backends/judgels-server-app/src/main/java/judgels/sandalphon/persistence/BaseProgrammingSubmissionDao.java @@ -10,7 +10,8 @@ public interface BaseProgrammingSubmissionDao select(); Map selectCounts(String containerJid, String userJid, Collection problemJids); - void updateContainer(String problemJid, String containerJid); + void updateContainerJid(String problemJid, String containerJid); + void deleteAllByProblemJid(String problemJid); Collection dump(PrintWriter output, String containerJid); interface BaseProgrammingSubmissionQueryBuilder extends QueryBuilder { diff --git a/judgels-backends/judgels-server-app/src/main/java/judgels/uriel/hibernate/ContestProgrammingGradingHibernateDao.java b/judgels-backends/judgels-server-app/src/main/java/judgels/uriel/hibernate/ContestProgrammingGradingHibernateDao.java index c3c0e3606..a03fde4bc 100644 --- a/judgels-backends/judgels-server-app/src/main/java/judgels/uriel/hibernate/ContestProgrammingGradingHibernateDao.java +++ b/judgels-backends/judgels-server-app/src/main/java/judgels/uriel/hibernate/ContestProgrammingGradingHibernateDao.java @@ -1,8 +1,14 @@ package judgels.uriel.hibernate; +import java.io.PrintWriter; +import java.util.Collection; +import java.util.List; import javax.inject.Inject; +import judgels.persistence.Model_; +import judgels.persistence.api.OrderDir; import judgels.persistence.hibernate.HibernateDaoData; import judgels.sandalphon.hibernate.AbstractProgrammingGradingHibernateDao; +import judgels.sandalphon.persistence.AbstractProgrammingGradingModel_; import judgels.uriel.persistence.ContestProgrammingGradingDao; import judgels.uriel.persistence.ContestProgrammingGradingModel; @@ -23,4 +29,33 @@ public ContestProgrammingGradingModel createGradingModel() { public Class getGradingModelClass() { return ContestProgrammingGradingModel.class; } + + @Override + public void dump(PrintWriter output, Collection submissionJids) { + List results = select().where(columnIn(AbstractProgrammingGradingModel_.submissionJid, submissionJids)).orderBy( + Model_.ID, OrderDir.ASC).all(); + if (results.isEmpty()) { + return; + } + + output.write("INSERT IGNORE INTO uriel_contest_programming_grading (jid, submissionJid, verdictCode, verdictName, score, details, createdBy, createdAt, updatedAt) VALUES\n"); + + for (int i = 0; i < results.size(); i++) { + ContestProgrammingGradingModel m = results.get(i); + if (i > 0) { + output.write(",\n"); + } + output.write(String.format("(%s, %s, %s, %s, %s, %s, %s, %s, %s)", + escape(m.jid), + escape(m.submissionJid), + escape(m.verdictCode), + escape(""), + escape(m.score), + escape(m.details), + escape(m.createdBy), + escape(m.createdAt), + escape(m.updatedAt))); + } + output.write(";\n"); + } }