You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Hydro/hydro/model/problem.js

84 lines
2.0 KiB
JavaScript

const
validator = require('../lib/validator'),
{ ProblemNotFoundError } = require('../error'),
db = require('../service/db.js'),
coll = db.collection('problem'),
coll_status = db.collection('problem.status');
/**
* @param {string} title
* @param {string} content
* @param {number} owner
* @param {number} pid
* @param {import('bson').ObjectID} data
* @param {string[]} category
* @param {string[]} tag
* @param {boolean} hidden
*/
async function add({
title,
content,
owner,
pid = null,
data = null,
category = [],
tag = [],
hidden = false
}) {
validator.checkTitle(title);
validator.checkContent(content);
await coll.insertOne({
content,
owner,
pid,
title,
data,
category,
tag,
hidden,
nSubmit: 0,
nAccept: 0
});
return pid;
}
async function get({ pid, uid }) {
pid = parseInt(pid) || pid;
let pdoc = await coll.findOne({ pid });
if (!pdoc) throw new ProblemNotFoundError(pid);
pdoc.psdoc = uid ?
await coll_status.findOne({ pid, uid }) :
null;
return pdoc;
}
async function getMany(query, sort, page, limit) {
return await coll.find(query).sort(sort).skip((page - 1) * limit).limit(limit).toArray();
}
async function edit(pid, $set) {
if ($set.title) validator.checkTitle($set.title);
if ($set.content) validator.checkContent($set.content);
await coll.findOneAndUpdate({ pid }, { $set });
let pdoc = await coll.findOne({ pid });
if (!pdoc) throw new ProblemNotFoundError(pid);
return pdoc;
}
async function count(query) {
return await coll.find(query).count();
}
async function random(query) {
let pdocs = coll.find(query);
let pcount = await pdocs.count();
if (pcount) {
let pdoc = await pdocs.skip(Math.floor(Math.random() * pcount)).limit(1).toArray()[0];
return pdoc.pid;
} else return null;
}
module.exports = {
add,
get,
getMany,
edit,
count,
random
};