Improves db query for demo- and abcd quizzes

parent 44a5a787
......@@ -62,34 +62,30 @@ class QuizDAO extends AbstractDAO {
}
public async getLastPersistedDemoQuizNumber(): Promise<number> {
return this.getLastPersistedNumberForQuizzes(await this.getAllPersistedDemoQuizzes());
}
public async getLastPersistedAbcdQuizNumberByLength(length: number): Promise<number> {
return this.getLastPersistedNumberForQuizzes(await this.getAllPersistedAbcdQuizzesByLength(length));
}
public getAllPersistedDemoQuizzes(): Promise<Array<Document & QuizModelItem>> {
return QuizModel.find({ name: /^demo quiz/i }).exec();
}
const quizzes = await QuizModel.find({ name: { $regex: new RegExp(`^(demo quiz) ([0-9]*)$`, 'i') } }).sort({
name: -1,
$natural: -1,
}).limit(1).exec();
if (!quizzes.length) {
return 0;
}
public async getAllPersistedAbcdQuizzes(): Promise<Array<Document & QuizModelItem>> {
const quizzes = await QuizModel.find({ name: /([a-zA-Z]*)(\s[0-9]*)/i }).exec();
return quizzes.filter((value) => {
return this.checkABCDOrdering(value.name.toLowerCase());
});
const splitted = quizzes[0].name.split(' ');
return parseInt(splitted[2], 10);
}
public async getAllPersistedAbcdQuizzesByLength(length: number): Promise<Array<Document & QuizModelItem>> {
const quizzes = await QuizModel.find({ name: { $gte: length } }).exec();
return quizzes.filter(val => {
const abcdString = val.name.toLowerCase().match(/([a-zA-Z]*)(\s[0-9]*)/i);
if (!abcdString || abcdString.length < 2) {
return false;
}
public async getLastPersistedAbcdQuizNumberByLength(length: number): Promise<number> {
const regexMatchString = new Array(length).fill('').map((val, index) => `${String.fromCharCode(65 + index)}{1}`).join('');
const quizzes = await QuizModel.find({ name: { $regex: new RegExp(`^(${regexMatchString}) ([0-9]*)$`, 'i') } }).sort({
name: -1,
$natural: -1,
}).limit(1).exec();
if (!quizzes.length) {
return 0;
}
return this.checkABCDOrdering(abcdString[1]) && val.questionList[0].answerOptionList.length === length;
});
const splitted = quizzes[0].name.split(' ');
return parseInt(splitted[1], 10);
}
public convertLegacyQuiz(legacyQuiz: any): Document & QuizModelItem {
......@@ -356,20 +352,6 @@ class QuizDAO extends AbstractDAO {
};
}
private checkABCDOrdering(quizname: string): boolean {
let ordered = true;
if (!quizname || quizname.length < 2 || quizname.charAt(0) !== 'a') {
return false;
}
for (let i = 1; i < quizname.length; i++) {
if (quizname.charCodeAt(i) !== quizname.charCodeAt(i - 1) + 1) {
ordered = false;
break;
}
}
return ordered;
}
private replaceTypeInformationOnLegacyQuiz(obj): object {
if (obj === null || typeof obj !== 'object') {
return obj;
......@@ -394,18 +376,6 @@ class QuizDAO extends AbstractDAO {
return obj;
}
private getLastPersistedNumberForQuizzes(data: Array<Document & QuizModelItem>): number {
let maxNumber = 0;
data.forEach((quiz => {
const name = quiz.name;
const currentNumber = parseInt(name.substring(name.lastIndexOf(' '), name.length), 10);
if (currentNumber > maxNumber) {
maxNumber = currentNumber;
}
}));
return maxNumber;
}
private getQuizByState(states: Array<QuizState>): Promise<Array<Document & QuizModelItem>> {
return QuizModel.find({ state: { $in: states } }).exec();
}
......
......@@ -51,7 +51,9 @@ export class QuizRouter extends AbstractRouter {
const quizName = params.quizName;
const member = await MemberDAO.getMemberByToken(token);
if (!quizName && (!token || !member)) {
if (!quizName && (
!token || !member
)) {
throw new UnauthorizedError(MessageProtocol.InsufficientPermissions);
}
......@@ -104,7 +106,8 @@ export class QuizRouter extends AbstractRouter {
};
}
@Get('/generate/demo/:languageId')
@Get('/generate/demo/:languageId') //
@ContentType('application/json')
public async generateDemoQuiz(
@Param('languageId') languageId: string, //
@Res() res: Response, //
......@@ -116,17 +119,24 @@ export class QuizRouter extends AbstractRouter {
if (!fs.existsSync(demoQuizPath)) {
demoQuizPath = path.join(basePath, 'en.demo_quiz.json');
}
const result: IQuiz = JSON.parse(fs.readFileSync(demoQuizPath).toString());
result.name = 'Demo Quiz ' + ((await QuizDAO.getLastPersistedDemoQuizNumber()) + 1);
result.name = 'Demo Quiz ' + (
(
await QuizDAO.getLastPersistedDemoQuizNumber()
) + 1
);
QuizDAO.convertLegacyQuiz(result);
res.setHeader('Response-Type', 'application/json');
return result;
} catch (ex) {
throw new InternalServerError(`File IO Error: ${ex}`);
}
}
@Get('/generate/abcd/:languageId/:answerLength?')
@Get('/generate/abcd/:languageId/:answerLength?') //
@ContentType('application/json')
public async generateAbcdQuiz(
@Param('languageId') languageId: string, //
@Param('answerLength') answerLength: number, //
......@@ -134,21 +144,25 @@ export class QuizRouter extends AbstractRouter {
): Promise<IQuiz> {
try {
answerLength = answerLength || 4;
answerLength = parseInt(String(answerLength), 10) || 4;
const basePath = path.join(staticStatistics.pathToAssets, 'predefined_quizzes', 'abcd_quiz');
let abcdQuizPath = path.join(basePath, `${languageId.toLowerCase()}.abcd_quiz.json`);
if (!fs.existsSync(abcdQuizPath)) {
abcdQuizPath = path.join(basePath, 'en.abcd_quiz.json');
}
const result: IQuiz = JSON.parse(fs.readFileSync(abcdQuizPath).toString());
let abcdName = '';
for (let i = 0; i < answerLength; i++) {
abcdName += String.fromCharCode(65 + i);
}
result.name = `${abcdName} ${((await QuizDAO.getLastPersistedAbcdQuizNumberByLength(answerLength)) + 1)}`;
const abcdName = new Array(answerLength).fill('').map((val, index) => `${String.fromCharCode(65 + index)}`).join('');
result.name = `${abcdName} ${(
(
await QuizDAO.getLastPersistedAbcdQuizNumberByLength(answerLength)
) + 1
)}`;
QuizDAO.convertLegacyQuiz(result);
res.setHeader('Response-Type', 'application/json');
return result;
} catch (ex) {
throw new InternalServerError(`File IO Error: ${ex}`);
}
......@@ -494,9 +508,13 @@ export class QuizRouter extends AbstractRouter {
if (existingQuiz) {
await QuizDAO.updateQuiz(existingQuiz.id, quiz);
return (await QuizDAO.getQuizByName(quiz.name)).toJSON();
return (
await QuizDAO.getQuizByName(quiz.name)
).toJSON();
} else {
return (await QuizDAO.addQuiz(quiz)).toJSON();
return (
await QuizDAO.addQuiz(quiz)
).toJSON();
}
}
......@@ -520,7 +538,9 @@ export class QuizRouter extends AbstractRouter {
quiz.state = QuizState.Inactive;
QuizDAO.convertLegacyQuiz(quiz);
return (await QuizDAO.addQuiz(quiz)).toJSON();
return (
await QuizDAO.addQuiz(quiz)
).toJSON();
}
@Delete('/:quizName')
......@@ -700,7 +720,9 @@ export class QuizRouter extends AbstractRouter {
@Get('/public')
private async getPublicQuizzes(@HeaderParam('authorization') privateKey: string): Promise<Array<QuizModelItem>> {
return (await QuizDAO.getAllPublicQuizzes()).filter(quiz => quiz.privateKey !== privateKey).map(quiz => quiz.toJSON());
return (
await QuizDAO.getAllPublicQuizzes()
).filter(quiz => quiz.privateKey !== privateKey).map(quiz => quiz.toJSON());
}
@Post('/public/init')
......@@ -714,7 +736,9 @@ export class QuizRouter extends AbstractRouter {
throw new UnauthorizedError('Unauthorized to create quiz');
}
const quiz = (await QuizDAO.getAllPublicQuizzes()).find(q => q.name === quizName);
const quiz = (
await QuizDAO.getAllPublicQuizzes()
).find(q => q.name === quizName);
if (!quiz) {
throw new NotFoundError('Quiz name not found');
}
......@@ -749,17 +773,23 @@ export class QuizRouter extends AbstractRouter {
@Get('/public/amount')
private async getPublicQuizAmount(@HeaderParam('authorization') privateKey: string): Promise<number> {
return (await this.getPublicQuizzes(privateKey)).length;
return (
await this.getPublicQuizzes(privateKey)
).length;
}
@Get('/public/own')
private async getOwnPublicQuizzes(@HeaderParam('authorization') privateKey: string): Promise<Array<QuizModelItem>> {
return (await QuizDAO.getAllPublicQuizzes()).filter(quiz => quiz.privateKey === privateKey).map(quiz => quiz.toJSON());
return (
await QuizDAO.getAllPublicQuizzes()
).filter(quiz => quiz.privateKey === privateKey).map(quiz => quiz.toJSON());
}
@Get('/public/amount/own')
private async getOwnPublicQuizAmount(@HeaderParam('authorization') privateKey: string): Promise<number> {
return (await this.getOwnPublicQuizzes(privateKey)).length;
return (
await this.getOwnPublicQuizzes(privateKey)
).length;
}
@Get('/')
......@@ -776,7 +806,9 @@ export class QuizRouter extends AbstractRouter {
const quizName = params.quizName;
const member = await MemberDAO.getMemberByToken(token);
if (!quizName && (!token || !member)) {
if (!quizName && (
!token || !member
)) {
throw new UnauthorizedError(MessageProtocol.InsufficientPermissions);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment