From 084688f6c143d3c0ad7baba81f4af769e855dc2f Mon Sep 17 00:00:00 2001 From: undefined Date: Fri, 11 Sep 2020 23:27:15 +0800 Subject: [PATCH] add interface for psdoc --- packages/hydrooj/src/interface.ts | 33 ++++--- packages/hydrooj/src/model/contest.ts | 2 +- packages/hydrooj/src/model/document.ts | 127 ++++++++++--------------- 3 files changed, 71 insertions(+), 91 deletions(-) diff --git a/packages/hydrooj/src/interface.ts b/packages/hydrooj/src/interface.ts index df2efdd69..8aadd345a 100644 --- a/packages/hydrooj/src/interface.ts +++ b/packages/hydrooj/src/interface.ts @@ -3,6 +3,8 @@ import { ObjectID, GridFSBucket } from 'mongodb'; import fs from 'fs'; import { Dictionary, NumericDictionary } from 'lodash'; +type document = typeof import('./model/document'); + export type NumberKeys = { [K in keyof O]: number extends O[K] ? K : never }[keyof O]; @@ -193,6 +195,14 @@ export interface StatusDoc { uid: number, } +export interface Document { + _id: ObjectID, + docId: any, + docType: number, + domainId: string, + owner: number, +} + export interface ProblemStatusDoc extends StatusDoc { docId: number, docType: 10, @@ -265,12 +275,9 @@ export interface TrainingNode { pids: number[], } -export interface Tdoc { - _id: ObjectID, - domainId: string, +export interface Tdoc extends Document { docId: ObjectID, - docType: number, - owner: number, + docType: document['TYPE_CONTEST'] | document['TYPE_HOMEWORK'] | document['TYPE_TRAINING'], beginAt: Date, endAt: Date, attend: number, @@ -278,6 +285,7 @@ export interface Tdoc { content: string, rule: string, pids: number[], + rated?: boolean, // For homework penaltySince?: Date, @@ -329,13 +337,11 @@ export interface Bdoc { } // Discussion -export interface Ddoc { - _id: ObjectID, - docType: number, +export interface Ddoc extends Document { + docType: document['TYPE_DISCUSSION'], docId: ObjectID, parentType: number, parentId: ObjectID | number | string, - owner: number, title: string, content: string, ip: string, @@ -343,16 +349,15 @@ export interface Ddoc { highlight: boolean, updateAt: Date, nReply: number, + views: number, } // Discussion reply -export interface Drdoc { - _id: ObjectID, - docType: number, +export interface Drdoc extends Document { + docType: document['TYPE_DISCUSSION_REPLY'], docId: ObjectID, - parentType: number, + parentType: document['TYPE_DISCUSSION'], parentId: ObjectID, - owner: number, ip: string, content: string, reply: Drrdoc[], diff --git a/packages/hydrooj/src/model/contest.ts b/packages/hydrooj/src/model/contest.ts index 2ae1e4c18..c01cc232f 100644 --- a/packages/hydrooj/src/model/contest.ts +++ b/packages/hydrooj/src/model/contest.ts @@ -557,7 +557,7 @@ export async function recalcStatus(domainId: string, tid: ObjectID, type: Type = tasks.push( document.revSetStatus( domainId, type, tid, - tsdoc.uid, tsdoc.rev, { journal, ...stats }, false, + tsdoc.uid, tsdoc.rev, { journal, ...stats }, ), ); } diff --git a/packages/hydrooj/src/model/document.ts b/packages/hydrooj/src/model/document.ts index d31aa8f54..297369fef 100644 --- a/packages/hydrooj/src/model/document.ts +++ b/packages/hydrooj/src/model/document.ts @@ -1,3 +1,4 @@ +/* eslint-disable object-curly-newline */ import assert from 'assert'; import { ObjectID, Cursor, FilterQuery, UpdateQuery, @@ -5,7 +6,7 @@ import { import * as db from '../service/db'; import * as bus from '../service/bus'; import { - Pdoc, Ddoc, Ufdoc, Drdoc, Tdoc, TrainingDoc, NumberKeys, ArrayKeys, ProblemStatusDoc, + Pdoc, Ddoc, Drdoc, Tdoc, TrainingDoc, NumberKeys, ArrayKeys, ProblemStatusDoc, } from '../interface'; type DocID = ObjectID | string | number; @@ -33,7 +34,7 @@ export interface DocType { [TYPE_DISCUSSION_REPLY]: Drdoc, [TYPE_CONTEST]: Tdoc, [TYPE_TRAINING]: TrainingDoc, - [TYPE_FILE]: Ufdoc, + [TYPE_FILE]: any, [TYPE_HOMEWORK]: Tdoc, } @@ -42,17 +43,17 @@ export interface DocStatusType { [key: number]: any } -export async function add( +export async function add( domainId: string, content: string, owner: number, - docType: K, docId: DocType[K]['docId'], - parentType?: number | null, parentId?: DocID, - args?: any, -): Promise -export async function add( + docType: T, docId: K, + parentType?: DocType[T]['parentType'], parentId?: DocType[T]['parentId'], + args?: Partial, +): Promise +export async function add( domainId: string, content: string, owner: number, - docType: K, docId: null, - parentType?: number, parentId?: DocID, - args?: any, + docType: T, docId: null, + parentType?: DocType[T]['parentType'], parentId?: DocType[T]['parentId'], + args?: Partial, ): Promise export async function add( domainId: string, content: string, owner: number, @@ -160,13 +161,7 @@ export async function push( const _id = new ObjectID(); const doc = await coll.findOneAndUpdate( { domainId, docType, docId }, - { - $push: { - [key]: { - ...args, content, owner, _id, - }, - }, - }, + { $push: { [key]: { ...args, content, owner, _id } } }, { returnOriginal: false }, ); return [doc.value, _id]; @@ -215,7 +210,7 @@ export async function getSub>( domainId: string, docType: T, docId: DocType[T]['docId'], - key: K, subId: ObjectID, args: UpdateQuery['$set'], + key: K, subId: DocType[T][K][0]['_id'], args: Partial, ): Promise { const $set = {}; for (const k in args) { @@ -246,12 +241,10 @@ export async function addToSet( +export async function getStatus( domainId: string, docType: K, docId: DocStatusType[K]['docId'], uid: number, ): Promise { - return collStatus.findOne({ - domainId, docType, docId, uid, - }); + return await collStatus.findOne({ domainId, docType, docId, uid }); } export function getMultiStatus( @@ -270,111 +263,93 @@ export async function setStatus( domainId: string, docType: K, docId: DocStatusType[K]['docId'], uid: number, args: UpdateQuery['$set'], ): Promise { const res = await collStatus.findOneAndUpdate( - { - domainId, docType, docId, uid, - }, + { domainId, docType, docId, uid }, { $set: args }, { upsert: true, returnOriginal: false }, ); return res.value; } -export function setMultiStatus( - domainId: string, docType: K, query: FilterQuery, args: UpdateQuery['$set'], +export async function setMultiStatus( + domainId: string, docType: K, query: FilterQuery, args: Partial, ) { - return collStatus.updateMany( + return await collStatus.updateMany( { domainId, docType, ...query }, { $set: args }, ); } -export async function setIfNotStatus( - domainId: string, docType: number, docId: DocID, uid: number, - key: string, value: number, ifNot: any, args: any, -) { +export async function setIfNotStatus( + domainId: string, docType: T, docId: DocStatusType[T]['docId'], uid: number, + key: K, value: number, ifNot: DocStatusType[T][K], args: Partial, +): Promise { const res = await collStatus.findOneAndUpdate( - { - domainId, docType, docId, uid, key: { $not: { $eq: ifNot } }, - }, + { domainId, docType, docId, uid, [key]: { $not: { $eq: ifNot } } }, { $set: { [key]: value, ...args } }, { upsert: true, returnOriginal: false }, ); return res.value; } -export async function cappedIncStatus( - domainId: string, docType: number, docId: DocID, uid: number, - key: string, value: number, minValue = -1, maxValue = 1, -) { +export async function cappedIncStatus( + domainId: string, docType: T, docId: DocStatusType[T]['docId'], uid: number, + key: NumberKeys, value: number, minValue = -1, maxValue = 1, +): Promise { assert(value !== 0); const $not = value > 0 ? { $gte: maxValue } : { $lte: minValue }; const res = await collStatus.findOneAndUpdate( - { - domainId, docType, docId, uid, [key]: { $not }, - }, + { domainId, docType, docId, uid, [key]: { $not } }, { $inc: { [key]: value } }, { upsert: true, returnOriginal: false }, ); return res.value; } -export async function incStatus( - domainId: string, docType: number, docId: DocID, uid: number, - key: string, value: number, -) { +export async function incStatus( + domainId: string, docType: T, docId: DocStatusType[T]['docId'], uid: number, + key: NumberKeys, value: number, +): Promise { const res = await collStatus.findOneAndUpdate( - { - domainId, docType, docId, uid, - }, + { domainId, docType, docId, uid }, { $inc: { [key]: value } }, { upsert: true, returnOriginal: false }, ); return res.value; } -export async function revPushStatus( - domainId: string, docType: number, docId: DocID, uid: number, - key: string, value: any, -) { +export async function revPushStatus( + domainId: string, docType: T, docId: DocStatusType[T]['docId'], uid: number, + key: ArrayKeys, value: any, +): Promise { const res = await collStatus.findOneAndUpdate( - { - domainId, docType, docId, uid, - }, + { domainId, docType, docId, uid }, { $push: { [key]: value }, $inc: { rev: 1 } }, { upsert: true, returnOriginal: false }, ); return res.value; } -export async function revInitStatus( - domainId: string, docType: number, docId: DocID, uid: number, -) { +export async function revInitStatus( + domainId: string, docType: T, docId: DocStatusType[T]['docId'], uid: number, +): Promise { const res = await collStatus.findOneAndUpdate( - { - domainId, docType, docId, uid, - }, + { domainId, docType, docId, uid }, { $inc: { rev: 1 } }, { upsert: true, returnOriginal: false }, ); return res.value; } -export async function revSetStatus( - domainId: string, docType: number, docId: DocID, uid: number, - rev: number, args: any, returnDoc = true, -) { - const filter = { - domainId, docType, docId, uid, rev, - }; +export async function revSetStatus( + domainId: string, docType: T, docId: DocStatusType[T]['docId'], uid: number, + rev: number, args: Partial, +): Promise { + const filter = { domainId, docType, docId, uid, rev }; const update = { $set: args, $inc: { rev: 1 } }; - if (returnDoc) { - const res = await collStatus.findOneAndUpdate(filter, update, { returnOriginal: false }); - return res.value; - } - return await collStatus.updateOne(filter, update); + const res = await collStatus.findOneAndUpdate(filter, update, { returnOriginal: false }); + return res.value; } -/* eslint-disable object-curly-newline */ async function ensureIndexes() { const ic = coll.createIndex.bind(coll); const is = collStatus.createIndex.bind(coll);