This commit is contained in:
214
functions/database.ts
Normal file
214
functions/database.ts
Normal file
@@ -0,0 +1,214 @@
|
||||
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({});
|
||||
}
|
||||
Reference in New Issue
Block a user