Files
mafuyu-kirisu/functions/database.ts
konchin 2d7361e937
Some checks failed
release-tag / release-image (push) Failing after 1m14s
initial commit
2024-10-11 19:49:58 +08:00

215 lines
6.1 KiB
TypeScript

import {Types} from 'mongoose';
import {User} from 'discord.js';
import {logger} from '../logger';
import {Session, sessionModel} from '../models/sessions';
import {Problem, problemModel} from '../models/problems';
import {Contest, contestModel} from '../models/contests';
export async function clearContests(): Promise<void>{
await contestModel.deleteMany({});
}
export async function clearProblems(): Promise<void>{
await problemModel.deleteMany({});
}
export async function clearSessions(): Promise<void>{
await sessionModel.deleteMany({});
}
export async function clearContest(channelId: string): Promise<void>{
await contestModel.deleteOne({channelId: channelId});
}
export async function createContest(channelId: string, startTime: number): Promise<boolean>{
const contest = await contestModel.findOne({channelId: channelId});
if(contest){
contest.startTime = startTime;
await contest.save();
return false;
}
const newContest = new contestModel({
channelId: channelId,
startTime: startTime,
problems: [],
});
await newContest.save();
return true;
}
export async function updateProblem(
user: User, problemId: string, channelId: string,
action: string, time: number): Promise<void>{
// find problem
let contest = await contestModel.findOne(
{channelId: channelId},
{problems: 1, _id: {"$toString": "$_id"}},
).populate({path: 'problems', select: 'problemId _id'});
if(contest === null){
logger.error(`contest didn't start`);
throw Error();
}
if(contest.problems.every(p => p.problemId != problemId)){
const newProblem = await new problemModel(
{problemId: problemId}, {}, {new: true}
).save();
await contestModel.updateOne(
{channelId: channelId},
{$push: {problems: newProblem}},
{new: true}
);
}
contest = await contestModel.findOne(
{channelId: channelId},
).populate({path: 'problems', select: 'problemId _id'});
const problem = (contest as Contest).problems.find(
p => p.problemId == problemId);
// update
switch(action){
case 'wa':{
await problemModel.findByIdAndUpdate(
(problem as Problem)._id,
{$push: {wa: time}},
{new: true}
);
}break;
case 'ac':{
await problemModel.findByIdAndUpdate(
(problem as Problem)._id,
{$set: {ac: time}},
{new: true}
);
}break;
}
}
export async function putCode(
user: User, problemId: string, channelId: string,
time: number, estimate: number): Promise<string>{
// find problem
let contest = await contestModel.findOne(
{channelId: channelId},
{problems: 1, _id: {"$toString": "$_id"}},
).populate({path: 'problems', select: 'problemId _id'});
if(contest === null){
logger.error(`contest didn't start`);
throw Error();
}
if(contest.problems.every(p => p.problemId != problemId)){
const newProblem = await new problemModel(
{problemId: problemId}, {}, {new: true}
).save();
await contestModel.updateOne(
{channelId: channelId},
{$push: {problems: newProblem}},
{new: true}
);
}
contest = await contestModel.findOne(
{channelId: channelId},
).populate({path: 'problems', select: 'problemId _id'});
const problem = (contest as Contest).problems.find(
p => p.problemId == problemId);
// update
const newSession = await new sessionModel(
{name: user.username, start: time, end: estimate},
{}, {new: true, upsert: true}
).save();
await problemModel.findByIdAndUpdate(
(problem as Problem)._id,
{$push: {code: newSession}},
{new: true}
);
return newSession._id.toString();
}
export async function putRead(
user: User, problemId: string, channelId: string,
time: number, estimate: number): Promise<string>{
// find problem
let contest = await contestModel.findOne(
{channelId: channelId},
{problems: 1, _id: {"$toString": "$_id"}},
).populate({path: 'problems', select: 'problemId _id'});
if(contest === null){
logger.error(`contest didn't start`);
throw Error();
}
if(contest.problems.every(p => p.problemId != problemId)){
const newProblem = await new problemModel(
{problemId: problemId}, {}, {new: true}
).save();
await contestModel.updateOne(
{channelId: channelId},
{$push: {problems: newProblem}},
{new: true}
);
}
contest = await contestModel.findOne(
{channelId: channelId},
).populate({path: 'problems', select: 'problemId _id'});
const problem = (contest as Contest).problems.find(
p => p.problemId == problemId);
// update
const newSession = await new sessionModel(
{name: user.username, start: time, end: estimate},
{}, {new: true, upsert: true}
).save();
await problemModel.findByIdAndUpdate(
(problem as Problem)._id,
{$push: {read: newSession}},
{new: true}
);
return newSession._id.toString();
}
export async function updateSession(sessionId: string, key: string, time: number): Promise<boolean>{
const session = await sessionModel.findOne({_id: sessionId});
if(session === null){
logger.error(`Session ${sessionId} not found.`);
return false;
}
switch(key){
case 'start':{
await sessionModel.updateOne(
{_id: sessionId}, {start: time}
);
}break;
case 'end':{
await sessionModel.updateOne(
{_id: sessionId}, {end: time}
);
}break;
}
return true;
}
export async function getContest(channelId: string): Promise<Contest | null>{
return await contestModel.findOne({channelId: channelId}).populate(
{path: 'problems', select: 'problemId _id'}
);
}
export async function getProblem(id: Types.ObjectId): Promise<Problem | null>{
return await problemModel.findById(id).populate(
{path: 'read code', select: 'name start end _id'}
);
}
export async function getSession(id: Types.ObjectId): Promise<Session | null>{
return await sessionModel.findById(id).populate('name start end _id');
}
export async function getAllSession(): Promise<Session[]>{
return await sessionModel.find({});
}
export async function getAllProblem(): Promise<Problem[]>{
return await problemModel.find({});
}
export async function getAllContest(): Promise<Contest[]>{
return await contestModel.find({});
}