mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
migrate: hustoj: support mysql 8.0
This commit is contained in:
2 files changed
+19
-27
No files matched your search
@@ -1,18 +1,16 @@
|
|||||||
{
|
{
|
||||||
"name": "@hydrooj/migrate",
|
"name": "@hydrooj/migrate",
|
||||||
"version": "0.2.3",
|
"version": "0.2.4",
|
||||||
"main": "index.ts",
|
"main": "index.ts",
|
||||||
"repository": "git@github.com:hydro-dev/Hydro.git",
|
"repository": "git@github.com:hydro-dev/Hydro.git",
|
||||||
"author": "undefined <i@undefined.moe>",
|
"author": "undefined <i@undefined.moe>",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/mysql": "^2.15.21",
|
|
||||||
"@types/turndown": "^5.0.1"
|
"@types/turndown": "^5.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"mariadb": "^3.1.0",
|
"mariadb": "^3.1.0",
|
||||||
"mongodb": "^5.1.0",
|
"mongodb": "^5.1.0",
|
||||||
"mysql": "^2.18.1",
|
|
||||||
"turndown": "^7.1.1"
|
"turndown": "^7.1.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/* eslint-disable no-tabs */
|
/* eslint-disable no-tabs */
|
||||||
/* eslint-disable no-await-in-loop */
|
/* eslint-disable no-await-in-loop */
|
||||||
import mysql from 'mysql';
|
import mariadb from 'mariadb';
|
||||||
import TurndownService from 'turndown';
|
import TurndownService from 'turndown';
|
||||||
import {
|
import {
|
||||||
buildContent, ContestModel, DomainModel, fs, noop, NotFoundError, ObjectId, postJudge, ProblemModel,
|
buildContent, ContestModel, DomainModel, fs, noop, NotFoundError, ObjectId, postJudge, ProblemModel,
|
||||||
@@ -53,21 +53,15 @@ export async function run({
|
|||||||
username, password, domainId, contestType = 'oi',
|
username, password, domainId, contestType = 'oi',
|
||||||
dataDir, rerun = true, randomMail = false,
|
dataDir, rerun = true, randomMail = false,
|
||||||
}, report: Function) {
|
}, report: Function) {
|
||||||
const src = mysql.createConnection({
|
const src = await mariadb.createConnection({
|
||||||
host,
|
host,
|
||||||
port,
|
port,
|
||||||
user: username,
|
user: username,
|
||||||
password,
|
password,
|
||||||
database: name,
|
database: name,
|
||||||
});
|
});
|
||||||
await new Promise((resolve, reject) => {
|
const query = (q: string) => new Promise<any[]>((res, rej) => {
|
||||||
src.connect((err) => (err ? reject(err) : resolve(null)));
|
src.query(q).then((r) => res(r)).catch((e) => rej(e));
|
||||||
});
|
|
||||||
const query = (q: string | mysql.Query) => new Promise<[values: any[], fields: mysql.FieldInfo[]]>((res, rej) => {
|
|
||||||
src.query(q, (err, val, fields) => {
|
|
||||||
if (err) rej(err);
|
|
||||||
else res([val, fields]);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
const target = await DomainModel.get(domainId);
|
const target = await DomainModel.get(domainId);
|
||||||
if (!target) throw new NotFoundError(domainId);
|
if (!target) throw new NotFoundError(domainId);
|
||||||
@@ -88,7 +82,7 @@ export async function run({
|
|||||||
school varchar 100 N 用户所在学校
|
school varchar 100 N 用户所在学校
|
||||||
*/
|
*/
|
||||||
const uidMap: Record<string, number> = {};
|
const uidMap: Record<string, number> = {};
|
||||||
const [udocs] = await query('SELECT * FROM `users`');
|
const udocs = await query('SELECT * FROM `users`');
|
||||||
const precheck = await UserModel.getMulti({ unameLower: { $in: udocs.map((u) => u.user_id.toLowerCase()) } }).toArray();
|
const precheck = await UserModel.getMulti({ unameLower: { $in: udocs.map((u) => u.user_id.toLowerCase()) } }).toArray();
|
||||||
if (precheck.length) throw new Error(`Conflict username: ${precheck.map((u) => u.unameLower).join(', ')}`);
|
if (precheck.length) throw new Error(`Conflict username: ${precheck.map((u) => u.unameLower).join(', ')}`);
|
||||||
for (const udoc of udocs) {
|
for (const udoc of udocs) {
|
||||||
@@ -121,7 +115,7 @@ export async function run({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const [admins] = await query("SELECT * FROM `privilege` WHERE `rightstr` = 'administrator'");
|
const admins = await query("SELECT * FROM `privilege` WHERE `rightstr` = 'administrator'");
|
||||||
for (const admin of admins) await DomainModel.setUserRole(domainId, uidMap[admin.user_id], 'root');
|
for (const admin of admins) await DomainModel.setUserRole(domainId, uidMap[admin.user_id], 'root');
|
||||||
const adminUids = admins.map((admin) => uidMap[admin.user_id]);
|
const adminUids = admins.map((admin) => uidMap[admin.user_id]);
|
||||||
report({ message: 'user finished' });
|
report({ message: 'user finished' });
|
||||||
@@ -148,11 +142,11 @@ export async function run({
|
|||||||
solution #optional
|
solution #optional
|
||||||
*/
|
*/
|
||||||
const pidMap: Record<string, number> = {};
|
const pidMap: Record<string, number> = {};
|
||||||
const [[{ 'count(*)': pcount }]] = await query('SELECT count(*) FROM `problem`');
|
const [{ 'count(*)': pcount }] = await query('SELECT count(*) FROM `problem`');
|
||||||
const step = 50;
|
const step = 50;
|
||||||
const pageCount = Math.ceil(pcount / step);
|
const pageCount = Math.ceil(Number(pcount) / step);
|
||||||
for (let pageId = 0; pageId < pageCount; pageId++) {
|
for (let pageId = 0; pageId < pageCount; pageId++) {
|
||||||
const [pdocs] = await query(`SELECT * FROM \`problem\` LIMIT ${pageId * step}, ${step}`);
|
const pdocs = await query(`SELECT * FROM \`problem\` LIMIT ${pageId * step}, ${step}`);
|
||||||
for (const pdoc of pdocs) {
|
for (const pdoc of pdocs) {
|
||||||
if (rerun) {
|
if (rerun) {
|
||||||
const opdoc = await ProblemModel.get(domainId, `P${pdoc.problem_id}`);
|
const opdoc = await ProblemModel.get(domainId, `P${pdoc.problem_id}`);
|
||||||
@@ -173,7 +167,7 @@ export async function run({
|
|||||||
);
|
);
|
||||||
pidMap[pdoc.problem_id] = pid;
|
pidMap[pdoc.problem_id] = pid;
|
||||||
}
|
}
|
||||||
const [cdoc] = await query(`SELECT * FROM \`privilege\` WHERE \`rightstr\` = 'p${pdoc.problem_id}'`);
|
const cdoc = await query(`SELECT * FROM \`privilege\` WHERE \`rightstr\` = 'p${pdoc.problem_id}'`);
|
||||||
const maintainer = [];
|
const maintainer = [];
|
||||||
for (let i = 1; i < cdoc.length; i++) maintainer.push(uidMap[cdoc[i].user_id]);
|
for (let i = 1; i < cdoc.length; i++) maintainer.push(uidMap[cdoc[i].user_id]);
|
||||||
await ProblemModel.edit(domainId, pidMap[pdoc.problem_id], {
|
await ProblemModel.edit(domainId, pidMap[pdoc.problem_id], {
|
||||||
@@ -205,9 +199,9 @@ export async function run({
|
|||||||
user_id char(48) 允许参加比赛用户列表
|
user_id char(48) 允许参加比赛用户列表
|
||||||
*/
|
*/
|
||||||
const tidMap: Record<string, string> = {};
|
const tidMap: Record<string, string> = {};
|
||||||
const [tdocs] = await query('SELECT * FROM `contest`');
|
const tdocs = await query('SELECT * FROM `contest`');
|
||||||
for (const tdoc of tdocs) {
|
for (const tdoc of tdocs) {
|
||||||
const [pdocs] = await query(`SELECT * FROM \`contest_problem\` WHERE \`contest_id\` = ${tdoc.contest_id}`);
|
const pdocs = await query(`SELECT * FROM \`contest_problem\` WHERE \`contest_id\` = ${tdoc.contest_id}`);
|
||||||
const pids = pdocs.map((i) => pidMap[i.problem_id]).filter((i) => i);
|
const pids = pdocs.map((i) => pidMap[i.problem_id]).filter((i) => i);
|
||||||
const tid = await ContestModel.add(
|
const tid = await ContestModel.add(
|
||||||
domainId, tdoc.title, tdoc.description || 'Description',
|
domainId, tdoc.title, tdoc.description || 'Description',
|
||||||
@@ -239,10 +233,10 @@ export async function run({
|
|||||||
lint_error int N ???
|
lint_error int N ???
|
||||||
judger char(16) N 判题机
|
judger char(16) N 判题机
|
||||||
*/
|
*/
|
||||||
const [[{ 'count(*)': rcount }]] = await query('SELECT count(*) FROM `solution`');
|
const [{ 'count(*)': rcount }] = await query('SELECT count(*) FROM `solution`');
|
||||||
const rpageCount = Math.ceil(rcount / step);
|
const rpageCount = Math.ceil(Number(rcount) / step);
|
||||||
for (let pageId = 0; pageId < rpageCount; pageId++) {
|
for (let pageId = 0; pageId < rpageCount; pageId++) {
|
||||||
const [rdocs] = await query(`SELECT * FROM \`solution\` LIMIT ${pageId * step}, ${step}`);
|
const rdocs = await query(`SELECT * FROM \`solution\` LIMIT ${pageId * step}, ${step}`);
|
||||||
for (const rdoc of rdocs) {
|
for (const rdoc of rdocs) {
|
||||||
const data: RecordDoc = {
|
const data: RecordDoc = {
|
||||||
status: statusMap[rdoc.result] || 0,
|
status: statusMap[rdoc.result] || 0,
|
||||||
@@ -262,11 +256,11 @@ export async function run({
|
|||||||
rejudged: false,
|
rejudged: false,
|
||||||
judger: 1,
|
judger: 1,
|
||||||
};
|
};
|
||||||
const [ceInfo] = await query(`SELECT \`error\` FROM \`compileinfo\` WHERE \`solution_id\` = ${rdoc.solution_id}`);
|
const ceInfo = await query(`SELECT \`error\` FROM \`compileinfo\` WHERE \`solution_id\` = ${rdoc.solution_id}`);
|
||||||
if (ceInfo[0]?.error) data.judgeTexts.push(ceInfo[0].error);
|
if (ceInfo[0]?.error) data.judgeTexts.push(ceInfo[0].error);
|
||||||
const [rtInfo] = await query(`SELECT \`error\` FROM \`runtimeinfo\` WHERE \`solution_id\` = ${rdoc.solution_id}`);
|
const rtInfo = await query(`SELECT \`error\` FROM \`runtimeinfo\` WHERE \`solution_id\` = ${rdoc.solution_id}`);
|
||||||
if (rtInfo[0]?.error) data.judgeTexts.push(rtInfo[0].error);
|
if (rtInfo[0]?.error) data.judgeTexts.push(rtInfo[0].error);
|
||||||
const [source] = await query(`SELECT \`source\` FROM \`source_code\` WHERE \`solution_id\` = ${rdoc.solution_id}`);
|
const source = await query(`SELECT \`source\` FROM \`source_code\` WHERE \`solution_id\` = ${rdoc.solution_id}`);
|
||||||
if (source[0]?.source) data.code = source[0].source;
|
if (source[0]?.source) data.code = source[0].source;
|
||||||
if (rdoc.contest_id) {
|
if (rdoc.contest_id) {
|
||||||
data.contest = new ObjectId(tidMap[rdoc.contest_id]);
|
data.contest = new ObjectId(tidMap[rdoc.contest_id]);
|
||||||
|
|||||||
Reference in new issue
Block a user