diff --git a/prisma/migrations/20250615052102_add_trim/migration.sql b/prisma/migrations/20250615052102_add_trim/migration.sql new file mode 100644 index 0000000..c185e55 --- /dev/null +++ b/prisma/migrations/20250615052102_add_trim/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "Problem" ADD COLUMN "trim" BOOLEAN NOT NULL DEFAULT false; diff --git a/prisma/migrations/20250615073315_init/migration.sql b/prisma/migrations/20250615073315_init/migration.sql new file mode 100644 index 0000000..56119e1 --- /dev/null +++ b/prisma/migrations/20250615073315_init/migration.sql @@ -0,0 +1,164 @@ +/* + Warnings: + + - The primary key for the `DockerConfig` table will be changed. If it partially fails, the table could be left without primary key constraint. + - The primary key for the `LanguageServerConfig` table will be changed. If it partially fails, the table could be left without primary key constraint. + - You are about to drop the column `createdAt` on the `Problem` table. All the data in the column will be lost. + - You are about to drop the column `isPublished` on the `Problem` table. All the data in the column will be lost. + - You are about to drop the column `updatedAt` on the `Problem` table. All the data in the column will be lost. + - You are about to drop the column `content` on the `Submission` table. All the data in the column will be lost. + - You are about to drop the column `timeUsage` on the `Submission` table. All the data in the column will be lost. + - The primary key for the `Template` table will be changed. If it partially fails, the table could be left without primary key constraint. + - You are about to drop the column `content` on the `Template` table. All the data in the column will be lost. + - You are about to drop the column `createdAt` on the `Testcase` table. All the data in the column will be lost. + - You are about to drop the column `updatedAt` on the `Testcase` table. All the data in the column will be lost. + - You are about to drop the column `timeUsage` on the `TestcaseResult` table. All the data in the column will be lost. + - You are about to drop the `ProblemLocalization` table. If the table is not empty, all the data it contains will be lost. + - You are about to drop the `TestcaseInput` table. If the table is not empty, all the data it contains will be lost. + - A unique constraint covering the columns `[language]` on the table `DockerConfig` will be added. If there are existing duplicate values, this will fail. + - A unique constraint covering the columns `[language]` on the table `LanguageServerConfig` will be added. If there are existing duplicate values, this will fail. + - Changed the type of `language` on the `DockerConfig` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `language` on the `LanguageServerConfig` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `protocol` on the `LanguageServerConfig` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Added the required column `description` to the `Problem` table without a default value. This is not possible if the table is not empty. + - Added the required column `solution` to the `Problem` table without a default value. This is not possible if the table is not empty. + - Added the required column `title` to the `Problem` table without a default value. This is not possible if the table is not empty. + - Made the column `userId` on table `Problem` required. This step will fail if there are existing NULL values in that column. + - Added the required column `code` to the `Submission` table without a default value. This is not possible if the table is not empty. + - Changed the type of `language` on the `Submission` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Added the required column `template` to the `Template` table without a default value. This is not possible if the table is not empty. + - Changed the type of `language` on the `Template` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Made the column `output` on table `TestcaseResult` required. This step will fail if there are existing NULL values in that column. + +*/ +-- CreateEnum +CREATE TYPE "EditorLanguage" AS ENUM ('c', 'cpp'); + +-- CreateEnum +CREATE TYPE "LanguageServerProtocol" AS ENUM ('ws', 'wss'); + +-- DropForeignKey +ALTER TABLE "Problem" DROP CONSTRAINT "Problem_userId_fkey"; + +-- DropForeignKey +ALTER TABLE "ProblemLocalization" DROP CONSTRAINT "ProblemLocalization_problemId_fkey"; + +-- DropForeignKey +ALTER TABLE "TestcaseInput" DROP CONSTRAINT "TestcaseInput_testcaseId_fkey"; + +-- AlterTable +ALTER TABLE "DockerConfig" DROP CONSTRAINT "DockerConfig_pkey", +DROP COLUMN "language", +ADD COLUMN "language" "EditorLanguage" NOT NULL, +ALTER COLUMN "compileOutputLimit" DROP DEFAULT, +ALTER COLUMN "runOutputLimit" DROP DEFAULT; + +-- AlterTable +ALTER TABLE "LanguageServerConfig" DROP CONSTRAINT "LanguageServerConfig_pkey", +DROP COLUMN "language", +ADD COLUMN "language" "EditorLanguage" NOT NULL, +DROP COLUMN "protocol", +ADD COLUMN "protocol" "LanguageServerProtocol" NOT NULL; + +-- AlterTable +ALTER TABLE "Problem" DROP COLUMN "createdAt", +DROP COLUMN "isPublished", +DROP COLUMN "updatedAt", +ADD COLUMN "description" TEXT NOT NULL, +ADD COLUMN "published" BOOLEAN NOT NULL DEFAULT false, +ADD COLUMN "solution" TEXT NOT NULL, +ADD COLUMN "title" TEXT NOT NULL, +ALTER COLUMN "memoryLimit" SET DEFAULT 128, +ALTER COLUMN "userId" SET NOT NULL; + +-- AlterTable +ALTER TABLE "Submission" DROP COLUMN "content", +DROP COLUMN "timeUsage", +ADD COLUMN "code" TEXT NOT NULL, +ADD COLUMN "executionTime" INTEGER, +DROP COLUMN "language", +ADD COLUMN "language" "EditorLanguage" NOT NULL; + +-- AlterTable +ALTER TABLE "Template" DROP CONSTRAINT "Template_pkey", +DROP COLUMN "content", +ADD COLUMN "template" TEXT NOT NULL, +DROP COLUMN "language", +ADD COLUMN "language" "EditorLanguage" NOT NULL, +ADD CONSTRAINT "Template_pkey" PRIMARY KEY ("problemId", "language"); + +-- AlterTable +ALTER TABLE "Testcase" DROP COLUMN "createdAt", +DROP COLUMN "updatedAt"; + +-- AlterTable +ALTER TABLE "TestcaseResult" DROP COLUMN "timeUsage", +ADD COLUMN "executionTime" INTEGER, +ALTER COLUMN "output" SET NOT NULL; + +-- AlterTable +ALTER TABLE "User" ALTER COLUMN "email" DROP NOT NULL; + +-- DropTable +DROP TABLE "ProblemLocalization"; + +-- DropTable +DROP TABLE "TestcaseInput"; + +-- DropEnum +DROP TYPE "Language"; + +-- DropEnum +DROP TYPE "Locale"; + +-- DropEnum +DROP TYPE "ProblemContentType"; + +-- DropEnum +DROP TYPE "Protocol"; + +-- CreateTable +CREATE TABLE "EditorLanguageConfig" ( + "language" "EditorLanguage" NOT NULL, + "label" TEXT NOT NULL, + "fileName" TEXT NOT NULL, + "fileExtension" TEXT NOT NULL +); + +-- CreateTable +CREATE TABLE "TestcaseData" ( + "id" TEXT NOT NULL, + "index" INTEGER NOT NULL, + "label" TEXT NOT NULL, + "value" TEXT NOT NULL, + "testcaseId" TEXT NOT NULL, + + CONSTRAINT "TestcaseData_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "EditorLanguageConfig_language_key" ON "EditorLanguageConfig"("language"); + +-- CreateIndex +CREATE UNIQUE INDEX "DockerConfig_language_key" ON "DockerConfig"("language"); + +-- CreateIndex +CREATE UNIQUE INDEX "LanguageServerConfig_language_key" ON "LanguageServerConfig"("language"); + +-- CreateIndex +CREATE INDEX "Problem_userId_idx" ON "Problem"("userId"); + +-- CreateIndex +CREATE INDEX "Problem_difficulty_idx" ON "Problem"("difficulty"); + +-- AddForeignKey +ALTER TABLE "Problem" ADD CONSTRAINT "Problem_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "LanguageServerConfig" ADD CONSTRAINT "LanguageServerConfig_language_fkey" FOREIGN KEY ("language") REFERENCES "EditorLanguageConfig"("language") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "DockerConfig" ADD CONSTRAINT "DockerConfig_language_fkey" FOREIGN KEY ("language") REFERENCES "EditorLanguageConfig"("language") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "TestcaseData" ADD CONSTRAINT "TestcaseData_testcaseId_fkey" FOREIGN KEY ("testcaseId") REFERENCES "Testcase"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/migrations/20250615082129_add_trim/migration.sql b/prisma/migrations/20250615082129_add_trim/migration.sql new file mode 100644 index 0000000..2318615 --- /dev/null +++ b/prisma/migrations/20250615082129_add_trim/migration.sql @@ -0,0 +1,156 @@ +/* + Warnings: + + - You are about to drop the column `description` on the `Problem` table. All the data in the column will be lost. + - You are about to drop the column `published` on the `Problem` table. All the data in the column will be lost. + - You are about to drop the column `solution` on the `Problem` table. All the data in the column will be lost. + - You are about to drop the column `title` on the `Problem` table. All the data in the column will be lost. + - You are about to drop the column `code` on the `Submission` table. All the data in the column will be lost. + - You are about to drop the column `executionTime` on the `Submission` table. All the data in the column will be lost. + - The primary key for the `Template` table will be changed. If it partially fails, the table could be left without primary key constraint. + - You are about to drop the column `template` on the `Template` table. All the data in the column will be lost. + - You are about to drop the column `executionTime` on the `TestcaseResult` table. All the data in the column will be lost. + - You are about to drop the `EditorLanguageConfig` table. If the table is not empty, all the data it contains will be lost. + - You are about to drop the `TestcaseData` table. If the table is not empty, all the data it contains will be lost. + - Changed the type of `language` on the `DockerConfig` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `language` on the `LanguageServerConfig` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `protocol` on the `LanguageServerConfig` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Added the required column `updatedAt` to the `Problem` table without a default value. This is not possible if the table is not empty. + - Added the required column `content` to the `Submission` table without a default value. This is not possible if the table is not empty. + - Changed the type of `language` on the `Submission` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Added the required column `content` to the `Template` table without a default value. This is not possible if the table is not empty. + - Changed the type of `language` on the `Template` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Added the required column `updatedAt` to the `Testcase` table without a default value. This is not possible if the table is not empty. + - Made the column `email` on table `User` required. This step will fail if there are existing NULL values in that column. + +*/ +-- CreateEnum +CREATE TYPE "Locale" AS ENUM ('en', 'zh'); + +-- CreateEnum +CREATE TYPE "Language" AS ENUM ('c', 'cpp'); + +-- CreateEnum +CREATE TYPE "Protocol" AS ENUM ('ws', 'wss'); + +-- CreateEnum +CREATE TYPE "ProblemContentType" AS ENUM ('TITLE', 'DESCRIPTION', 'SOLUTION'); + +-- DropForeignKey +ALTER TABLE "DockerConfig" DROP CONSTRAINT "DockerConfig_language_fkey"; + +-- DropForeignKey +ALTER TABLE "LanguageServerConfig" DROP CONSTRAINT "LanguageServerConfig_language_fkey"; + +-- DropForeignKey +ALTER TABLE "Problem" DROP CONSTRAINT "Problem_userId_fkey"; + +-- DropForeignKey +ALTER TABLE "TestcaseData" DROP CONSTRAINT "TestcaseData_testcaseId_fkey"; + +-- DropIndex +DROP INDEX "DockerConfig_language_key"; + +-- DropIndex +DROP INDEX "LanguageServerConfig_language_key"; + +-- DropIndex +DROP INDEX "Problem_difficulty_idx"; + +-- DropIndex +DROP INDEX "Problem_userId_idx"; + +-- AlterTable +ALTER TABLE "DockerConfig" ALTER COLUMN "compileOutputLimit" SET DEFAULT 1048576, +ALTER COLUMN "runOutputLimit" SET DEFAULT 1048576, +DROP COLUMN "language", +ADD COLUMN "language" "Language" NOT NULL, +ADD CONSTRAINT "DockerConfig_pkey" PRIMARY KEY ("language"); + +-- AlterTable +ALTER TABLE "LanguageServerConfig" DROP COLUMN "language", +ADD COLUMN "language" "Language" NOT NULL, +DROP COLUMN "protocol", +ADD COLUMN "protocol" "Protocol" NOT NULL, +ADD CONSTRAINT "LanguageServerConfig_pkey" PRIMARY KEY ("language"); + +-- AlterTable +ALTER TABLE "Problem" DROP COLUMN "description", +DROP COLUMN "published", +DROP COLUMN "solution", +DROP COLUMN "title", +ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, +ADD COLUMN "isPublished" BOOLEAN NOT NULL DEFAULT false, +ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL, +ALTER COLUMN "memoryLimit" SET DEFAULT 134217728, +ALTER COLUMN "userId" DROP NOT NULL; + +-- AlterTable +ALTER TABLE "Submission" DROP COLUMN "code", +DROP COLUMN "executionTime", +ADD COLUMN "content" TEXT NOT NULL, +ADD COLUMN "timeUsage" INTEGER, +DROP COLUMN "language", +ADD COLUMN "language" "Language" NOT NULL; + +-- AlterTable +ALTER TABLE "Template" DROP CONSTRAINT "Template_pkey", +DROP COLUMN "template", +ADD COLUMN "content" TEXT NOT NULL, +DROP COLUMN "language", +ADD COLUMN "language" "Language" NOT NULL, +ADD CONSTRAINT "Template_pkey" PRIMARY KEY ("problemId", "language"); + +-- AlterTable +ALTER TABLE "Testcase" ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, +ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL; + +-- AlterTable +ALTER TABLE "TestcaseResult" DROP COLUMN "executionTime", +ADD COLUMN "timeUsage" INTEGER, +ALTER COLUMN "output" DROP NOT NULL; + +-- AlterTable +ALTER TABLE "User" ALTER COLUMN "email" SET NOT NULL; + +-- DropTable +DROP TABLE "EditorLanguageConfig"; + +-- DropTable +DROP TABLE "TestcaseData"; + +-- DropEnum +DROP TYPE "EditorLanguage"; + +-- DropEnum +DROP TYPE "LanguageServerProtocol"; + +-- CreateTable +CREATE TABLE "ProblemLocalization" ( + "problemId" TEXT NOT NULL, + "locale" "Locale" NOT NULL, + "type" "ProblemContentType" NOT NULL, + "content" TEXT NOT NULL, + + CONSTRAINT "ProblemLocalization_pkey" PRIMARY KEY ("problemId","locale","type") +); + +-- CreateTable +CREATE TABLE "TestcaseInput" ( + "id" TEXT NOT NULL, + "index" INTEGER NOT NULL, + "name" TEXT NOT NULL, + "value" TEXT NOT NULL, + "testcaseId" TEXT NOT NULL, + + CONSTRAINT "TestcaseInput_pkey" PRIMARY KEY ("id") +); + +-- AddForeignKey +ALTER TABLE "Problem" ADD CONSTRAINT "Problem_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "ProblemLocalization" ADD CONSTRAINT "ProblemLocalization_problemId_fkey" FOREIGN KEY ("problemId") REFERENCES "Problem"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "TestcaseInput" ADD CONSTRAINT "TestcaseInput_testcaseId_fkey" FOREIGN KEY ("testcaseId") REFERENCES "Testcase"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/migrations/20250616085459_refactor_trim_to_is_trim/migration.sql b/prisma/migrations/20250616085459_refactor_trim_to_is_trim/migration.sql new file mode 100644 index 0000000..20477bf --- /dev/null +++ b/prisma/migrations/20250616085459_refactor_trim_to_is_trim/migration.sql @@ -0,0 +1,9 @@ +/* + Warnings: + + - You are about to drop the column `trim` on the `Problem` table. All the data in the column will be lost. + +*/ +-- AlterTable +ALTER TABLE "Problem" DROP COLUMN "trim", +ADD COLUMN "isTrim" BOOLEAN NOT NULL DEFAULT false; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index e56f09e..17488cd 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -80,6 +80,7 @@ model Problem { displayId Int @unique difficulty Difficulty @default(EASY) isPublished Boolean @default(false) + isTrim Boolean @default(false) timeLimit Int @default(1000) memoryLimit Int @default(134217728) diff --git a/prisma/seed.ts b/prisma/seed.ts index 02f360a..82d24e5 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -41,6 +41,7 @@ const problemData: Prisma.ProblemCreateInput[] = [ displayId: 1000, difficulty: "EASY", isPublished: true, + isTrim: true, localizations: { create: [ { @@ -734,6 +735,7 @@ int main() { displayId: 1001, difficulty: "MEDIUM", isPublished: true, + isTrim: true, localizations: { create: [ { @@ -1261,6 +1263,7 @@ int main() { displayId: 1002, difficulty: "HARD", isPublished: true, + isTrim: true, localizations: { create: [ { diff --git a/src/app/actions/run.ts b/src/app/actions/run.ts index e2b65fb..4ad0061 100644 --- a/src/app/actions/run.ts +++ b/src/app/actions/run.ts @@ -28,7 +28,8 @@ const startRun = ( joinedInputs: string, timeLimit: number, memoryLimit: number, - expectedOutput: string + expectedOutput: string, + isTrim: boolean, ): Promise => { return new Promise((resolve, reject) => { runExec.start({ hijack: true }, async (error, stream) => { @@ -71,7 +72,7 @@ const startRun = ( const exitCode = (await runExec.inspect()).ExitCode; const timeUsage = Date.now() - startTime; if (exitCode === 0) { - const isCorrect = stdout.trim() === expectedOutput; + const isCorrect = isTrim ? stdout.trim() === expectedOutput.trim() : stdout === expectedOutput; await prisma.testcaseResult.create({ data: { isCorrect, @@ -131,7 +132,8 @@ const executeRun = async ( submissionId: string, timeLimit: number, memoryLimit: number, - testcases: Testcase[] + testcases: Testcase[], + isTrim: boolean ): Promise => { for (const testcase of testcases) { const inputs = await prisma.testcaseInput.findMany({ @@ -169,7 +171,8 @@ const executeRun = async ( joinedInputs, timeLimit, memoryLimit, - testcase.expectedOutput + testcase.expectedOutput, + isTrim ); if (status !== Status.RU) { @@ -228,7 +231,7 @@ export const run = async ( testcases: Testcase[] ): Promise => { const { runOutputLimit } = config; - const { timeLimit, memoryLimit } = problem; + const { timeLimit, memoryLimit, isTrim } = problem; await prisma.submission.update({ where: { @@ -248,6 +251,7 @@ export const run = async ( submissionId, timeLimit, memoryLimit, - testcases + testcases, + isTrim ); };