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 250cd0443..906231cf7 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.moveProblemToChapterTask()); env.admin().addTask(component.problemSetStatsTask()); env.admin().addTask(component.contestStatsTask()); env.admin().addTask(component.submissionsDuplexToAwsTask()); 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 51f210a4b..47cf02f55 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,8 @@ import judgels.jerahmeel.course.chapter.CourseChapterResource; import judgels.jerahmeel.curriculum.CurriculumResource; import judgels.jerahmeel.hibernate.JerahmeelHibernateDaoModule; +import judgels.jerahmeel.problem.MoveProblemToChapterTask; +import judgels.jerahmeel.problem.ProblemModule; import judgels.jerahmeel.problem.ProblemResource; import judgels.jerahmeel.problem.ProblemTagResource; import judgels.jerahmeel.problemset.ProblemSetResource; @@ -59,6 +61,7 @@ GabrielClientModule.class, // Features + ProblemModule.class, SubmissionModule.class, ItemSubmissionModule.class, StatsModule.class @@ -82,6 +85,8 @@ public interface JerahmeelComponent { JudgelsScheduler scheduler(); GradingResponsePoller gradingResponsePoller(); + + MoveProblemToChapterTask moveProblemToChapterTask(); ProblemSetStatsTask problemSetStatsTask(); ContestStatsTask contestStatsTask(); SubmissionsDuplexToAwsTask submissionsDuplexToAwsTask(); 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 ea241ca79..40fa12dd2 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 @@ -5,6 +5,7 @@ import judgels.jerahmeel.persistence.ProgrammingSubmissionModel; import judgels.persistence.hibernate.HibernateDaoData; import judgels.sandalphon.hibernate.AbstractProgrammingSubmissionHibernateDao; +import org.hibernate.query.Query; public class ProgrammingSubmissionHibernateDao extends AbstractProgrammingSubmissionHibernateDao @@ -19,4 +20,16 @@ public ProgrammingSubmissionHibernateDao(HibernateDaoData data) { public ProgrammingSubmissionModel createSubmissionModel() { return new ProgrammingSubmissionModel(); } + + @Override + public void updateContainer(String problemJid, String containerJid) { + Query query = currentSession().createQuery( + "UPDATE jerahmeel_programming_submission " + + "SET containerJid = :containerJid " + + "WHERE problemJid = :problemJid"); + + query.setParameter("containerJid", containerJid); + query.setParameter("problemJid", problemJid); + query.executeUpdate(); + } } 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 new file mode 100644 index 000000000..ce41b592d --- /dev/null +++ b/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/problem/MoveProblemToChapterTask.java @@ -0,0 +1,96 @@ +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.ChapterDao; +import judgels.jerahmeel.persistence.ChapterModel; +import judgels.jerahmeel.persistence.ChapterProblemDao; +import judgels.jerahmeel.persistence.ChapterProblemModel; +import judgels.jerahmeel.persistence.ProblemSetProblemDao; +import judgels.jerahmeel.persistence.ProblemSetProblemModel; +import judgels.jerahmeel.persistence.ProgrammingSubmissionDao; +import judgels.sandalphon.api.problem.ProblemType; +import judgels.sandalphon.persistence.ProblemDao; +import judgels.sandalphon.persistence.ProblemModel; + +public class MoveProblemToChapterTask extends Task { + private final ProblemDao problemDao; + private final ChapterDao chapterDao; + private final ChapterProblemDao chapterProblemDao; + private final ProblemSetProblemDao problemSetProblemDao; + private final ProgrammingSubmissionDao programmingSubmissionDao; + + public MoveProblemToChapterTask( + ProblemDao problemDao, + ChapterDao chapterDao, + ChapterProblemDao chapterProblemDao, + ProblemSetProblemDao problemSetProblemDao, + ProgrammingSubmissionDao programmingSubmissionDao) { + + super("jerahmeel-move-problem-to-chapter"); + + this.problemDao = problemDao; + this.chapterDao = chapterDao; + this.chapterProblemDao = chapterProblemDao; + this.problemSetProblemDao = problemSetProblemDao; + this.programmingSubmissionDao = programmingSubmissionDao; + } + + @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); + + List toChapterJids = parameters.get("toChapterJid"); + if (toChapterJids == null || toChapterJids.isEmpty()) { + return; + } + String toChapterJid = toChapterJids.get(0); + + List aliases = parameters.get("alias"); + if (aliases == null || aliases.isEmpty()) { + return; + } + String alias = aliases.get(0); + + Optional maybeProblemModel = problemDao.selectBySlug(problemSlug); + if (maybeProblemModel.isEmpty()) { + return; + } + String problemJid = maybeProblemModel.get().jid; + + Optional maybeChapterModel = chapterDao.selectByJid(toChapterJid); + if (maybeChapterModel.isEmpty()) { + return; + } + + Optional maybeChapterProblemModel = chapterProblemDao.selectByProblemJid(problemJid); + if (maybeChapterProblemModel.isPresent()) { + ChapterProblemModel model = maybeChapterProblemModel.get(); + + model.chapterJid = toChapterJid; + model.alias = alias; + chapterProblemDao.update(model); + } else { + ChapterProblemModel model = new ChapterProblemModel(); + model.chapterJid = toChapterJid; + model.alias = alias; + model.problemJid = problemJid; + model.type = ProblemType.PROGRAMMING.name(); + chapterProblemDao.insert(model); + } + + List problemSetProblemModels = problemSetProblemDao.selectAllByProblemJid(problemJid); + problemSetProblemModels.forEach(problemSetProblemDao::delete); + + programmingSubmissionDao.updateContainer(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 new file mode 100644 index 000000000..6ec7f2956 --- /dev/null +++ b/judgels-backends/judgels-server-app/src/main/java/judgels/jerahmeel/problem/ProblemModule.java @@ -0,0 +1,42 @@ +package judgels.jerahmeel.problem; + +import dagger.Module; +import dagger.Provides; +import io.dropwizard.hibernate.UnitOfWorkAwareProxyFactory; +import javax.inject.Singleton; +import judgels.jerahmeel.persistence.ChapterDao; +import judgels.jerahmeel.persistence.ChapterProblemDao; +import judgels.jerahmeel.persistence.ProblemSetProblemDao; +import judgels.jerahmeel.persistence.ProgrammingSubmissionDao; +import judgels.sandalphon.persistence.ProblemDao; + +@Module +public class ProblemModule { + private ProblemModule() {} + + @Provides + @Singleton + static MoveProblemToChapterTask problemMoveToChapterTask( + UnitOfWorkAwareProxyFactory unitOfWorkAwareProxyFactory, + ProblemDao problemDao, + ChapterDao chapterDao, + ChapterProblemDao chapterProblemDao, + ProblemSetProblemDao problemSetProblemDao, + ProgrammingSubmissionDao programmingSubmissionDao) { + + return unitOfWorkAwareProxyFactory.create( + MoveProblemToChapterTask.class, + new Class[] { + ProblemDao.class, + ChapterDao.class, + ChapterProblemDao.class, + ProblemSetProblemDao.class, + ProgrammingSubmissionDao.class}, + new Object[] { + problemDao, + chapterDao, + chapterProblemDao, + problemSetProblemDao, + programmingSubmissionDao}); + } +} 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 d57c0027b..87cd82228 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 @@ -62,6 +62,11 @@ public Map selectCounts(String containerJid, String userJid, Colle .collect(Collectors.toMap(tuple -> tuple.get(0, String.class), tuple -> tuple.get(1, Long.class))); } + @Override + public void updateContainer(String problemJid, String containerJid) { + throw new UnsupportedOperationException(); + } + @Override public Collection dump(PrintWriter output, String containerJid) { List results = select().whereContainerIs(containerJid).orderBy(Model_.ID, OrderDir.ASC).all(); 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 5c15cd5f1..d90c276af 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,6 +10,7 @@ public interface BaseProgrammingSubmissionDao select(); Map selectCounts(String containerJid, String userJid, Collection problemJids); + void updateContainer(String problemJid, String containerJid); Collection dump(PrintWriter output, String containerJid); interface BaseProgrammingSubmissionQueryBuilder extends QueryBuilder {