From 1a857ae40aec7ac5ba119bad845bffefeb0bb491 Mon Sep 17 00:00:00 2001 From: undefined Date: Thu, 25 Nov 2021 19:35:37 +0800 Subject: [PATCH] core: better pid sort method --- packages/hydrooj/package.json | 2 +- packages/hydrooj/src/handler/problem.ts | 2 +- packages/hydrooj/src/interface.ts | 1 + packages/hydrooj/src/model/problem.ts | 15 ++++++++++++--- packages/hydrooj/src/upgrade.ts | 12 ++++++++++++ 5 files changed, 27 insertions(+), 5 deletions(-) diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index c9762bfa5..32751d32c 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "3.1.35", + "version": "3.1.36", "bin": "bin/hydrooj.js", "main": "src/loader", "module": "src/loader", diff --git a/packages/hydrooj/src/handler/problem.ts b/packages/hydrooj/src/handler/problem.ts index aef60b280..69bc69c58 100644 --- a/packages/hydrooj/src/handler/problem.ts +++ b/packages/hydrooj/src/handler/problem.ts @@ -148,7 +148,7 @@ export class ProblemMainHandler extends ProblemHandler { await bus.serial('problem/list', query, this); // eslint-disable-next-line prefer-const let [pdocs, ppcount, pcount] = await paginate( - problem.getMulti(domainId, query).sort({ pid: 1, docId: 1 }), + problem.getMulti(domainId, query).sort({ sort: 1, docId: 1 }), page, system.get('pagination.problem'), ); diff --git a/packages/hydrooj/src/interface.ts b/packages/hydrooj/src/interface.ts index 7226bbda0..1fe3e1321 100644 --- a/packages/hydrooj/src/interface.ts +++ b/packages/hydrooj/src/interface.ts @@ -242,6 +242,7 @@ declare module './model/problem' { html?: boolean; stats?: any; difficulty?: number; + sort?: string; reference?: { domainId: string; pid: number; diff --git a/packages/hydrooj/src/model/problem.ts b/packages/hydrooj/src/model/problem.ts index 87772950c..0ee2331a3 100644 --- a/packages/hydrooj/src/model/problem.ts +++ b/packages/hydrooj/src/model/problem.ts @@ -21,6 +21,10 @@ import storage from './storage'; export interface ProblemDoc extends Document { } export type Field = keyof ProblemDoc; +function sortable(source: string) { + return source.replace(/(\d+)/g, (str) => '0'.repeat(6 - str.length) + str); +} + export class ProblemModel { static PROJECTION_LIST: Field[] = [ '_id', 'domainId', 'docType', 'docId', 'pid', @@ -92,7 +96,7 @@ export class ProblemModel { content: string, owner: number, tag: string[] = [], hidden = false, ) { const args: Partial = { - title, tag, hidden, nSubmit: 0, nAccept: 0, + title, tag, hidden, nSubmit: 0, nAccept: 0, sort: sortable(pid || `P${docId}`), }; if (pid) args.pid = pid; await bus.serial('problem/before-add', domainId, content, owner, docId, args); @@ -125,7 +129,7 @@ export class ProblemModel { } static getMulti(domainId: string, query: FilterQuery, projection = ProblemModel.PROJECTION_LIST) { - return document.getMulti(domainId, document.TYPE_PROBLEM, query, projection); + return document.getMulti(domainId, document.TYPE_PROBLEM, query, projection).sort({ sort: 1 }); } static getStatus(domainId: string, docId: number, uid: number) { @@ -138,7 +142,12 @@ export class ProblemModel { static async edit(domainId: string, _id: number, $set: Partial): Promise { const delpid = $set.pid === ''; - if (delpid) delete $set.pid; + if (delpid) { + delete $set.pid; + $set.sort = sortable(`P${_id}`); + } else if ($set.pid) { + $set.sort = sortable($set.pid); + } await bus.serial('problem/before-edit', $set); const result = await document.set(domainId, document.TYPE_PROBLEM, _id, $set, delpid ? { pid: '' } : undefined); await bus.emit('problem/edit', result); diff --git a/packages/hydrooj/src/upgrade.ts b/packages/hydrooj/src/upgrade.ts index fe67023e9..4eab76b07 100644 --- a/packages/hydrooj/src/upgrade.ts +++ b/packages/hydrooj/src/upgrade.ts @@ -648,6 +648,18 @@ const scripts: UpgradeScript[] = [ } return true; }, + async function _54_55() { + const _FRESH_INSTALL_IGNORE = 1; + const bulk = db.collection('document').initializeUnorderedBulkOp(); + function sortable(source: string) { + return source.replace(/(\d+)/g, (str) => '0'.repeat(6 - str.length) + str); + } + await iterateAllProblem(['pid', '_id'], async (pdoc) => { + bulk.find({ _id: pdoc._id }).updateOne({ $set: { sort: sortable(pdoc.pid || `P${pdoc.docId}`) } }); + }); + if (bulk.length) await bulk.execute(); + return true; + }, ]; export default scripts;