Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/Cyber-Labs/cl-judge into …
Browse files Browse the repository at this point in the history
…submission-backend
  • Loading branch information
cjchirag7 committed Dec 20, 2020
2 parents 2ed7425 + 1335688 commit d0f9272
Show file tree
Hide file tree
Showing 22 changed files with 626 additions and 37 deletions.
12 changes: 9 additions & 3 deletions server/database.sql
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,8 @@ CREATE TABLE `leaderboard` (
`id` int NOT NULL AUTO_INCREMENT,
`username` varchar(45) NOT NULL,
`contest_id` int NOT NULL,
`score` int NOT NULL,
`total_time` timestamp NOT NULL,
`total_score` int NOT NULL,
`total_time` time NOT NULL,
`attempted_count` int NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique_contests_users` (`username`,`contest_id`),
Expand Down Expand Up @@ -256,6 +256,9 @@ CREATE TABLE `questions_tags` (
-- Table structure for table 'mcq_submissions'
--

DROP TABLE IF EXISTS `mcq_submissions`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `mcq_submissions` (
`id` int NOT NULL AUTO_INCREMENT,
`question_id` int NOT NULL,
Expand All @@ -281,12 +284,15 @@ CREATE TABLE `mcq_submissions` (
-- Table structure for table 'subjective_submissions'
--

DROP TABLE IF EXISTS `subjective_submissions`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `subjective_submissions` (
`id` int NOT NULL AUTO_INCREMENT,
`question_id` int NOT NULL,
`contest_id` int NOT NULL,
`username` varchar(45) NOT NULL,
`response` int NOT NULL,
`response` text NOT NULL,
`submission_time` timestamp NOT NULL,
`score` int DEFAULT '0',
`judged` tinyint DEFAULT '0',
Expand Down
33 changes: 33 additions & 0 deletions server/models/contests/getAllParticipants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const { pool } = require('../database')

/**
*
* @param {*} param0
* @param {String} param0.username
* @param {Object} param0.params
* @return {Promise}
*
*/

function getAllParticipants({ username, params }) {
return new Promise((resolve, reject) => {
const { contest_id: contestId } = params
pool.query(
`SELECT participant FROM contests_participants WHERE EXISTS(SELECT 1 FROM contests_participants WHERE contest_id=? AND participant=?) AND contest_id = ?`,
[contestId, username, contestId],
(error, results) => {
if (error || results === undefined) {
return reject(error)
}
if (!results.length) {
return reject(
'Either the contest ID is invalid or you have not yet registered for the contest'
)
}
return resolve(results)
}
)
})
}

module.exports = getAllParticipants
35 changes: 35 additions & 0 deletions server/models/contests/getAllParticipantsDetails.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const { pool } = require('../database')

/**
*
* @param {*} param0
* @param {String} param0.username
* @param {Object} param0.params
* @return {Promise}
*
*/

function getAllParticipantsDetails({ username, params }) {
return new Promise((resolve, reject) => {
const { contest_id: contestId } = params
pool.query(
`SELECT username, full_name, admission_number, email, mobile, department, course, admission_year, profile_img FROM users u
INNER JOIN contests_participants cp ON u.username = cp.participant
WHERE EXISTS(SELECT 1 FROM contests_moderators WHERE contest_id=? AND moderator=?) AND cp.contest_id=?`,
[contestId, username, contestId],
(error, results) => {
if (error || results === undefined) {
return reject(error)
}
if (!results.length) {
return reject(
'Either no one has yet participated or the user do not have required permissions'
)
}
return resolve(results)
}
)
})
}

module.exports = getAllParticipantsDetails
33 changes: 33 additions & 0 deletions server/models/contests/getContest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const { pool } = require('../../models/database')

/**
* @param {*} param0
* @param {String} param0.username
* @param {Object} param0.params
* @return {Promise}
*/

function getContest({ username, params }) {
return new Promise((resolve, reject) => {
const { contest_id: contestId } = params
pool.query(
`SELECT id, creator, name, start_time, end_time, about, rules, prizes, participants_count FROM contests WHERE id=?
AND (public=1 OR EXISTS(SELECT 1 FROM contests_groups cg INNER JOIN user_groups ug ON cg.group_id = ug.group_id
WHERE ug.username=? AND cg.contest_id=?))`,
[contestId, username, contestId],
(error, results) => {
if (error || results === undefined) {
return reject(error)
}
if (!results || !results.length) {
return reject(
'The contest is private and user do not belongs to any eligible groups'
)
}
return resolve(results)
}
)
})
}

module.exports = getContest
33 changes: 33 additions & 0 deletions server/models/contests/getContestDetails.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const { pool } = require('../../models/database')

/**
* @param {*} param0
* @param {String} param0.username
* @param {Object} param0.params
* @param {Object} param0.query
* @return {Promise}
*/

function getContestDetails({ username, params, query }) {
return new Promise((resolve, reject) => {
const onlyName = query.only_name || false
const { contest_id: contestId } = params
let sqlQuery = `SELECT * from contests WHERE EXISTS(SELECT 1 FROM contests_moderators WHERE contest_id=? AND moderator=?) AND id=?`
if (onlyName) {
sqlQuery = `SELECT name from contests WHERE EXISTS(SELECT 1 FROM contests_moderators WHERE contest_id=? AND moderator=?) AND id=?`
}
pool.query(sqlQuery, [contestId, username, contestId], (error, results) => {
if (error || results === undefined) {
return reject(error)
}
if (!results.length) {
return reject(
'Invalid contest Id or the user do not have required permissions'
)
}
return resolve(results)
})
})
}

module.exports = getContestDetails
31 changes: 31 additions & 0 deletions server/models/contests/getContestModerators.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const { pool } = require('../../models/database')

/**
* @param {*} param0
* @param {String} param0.username
* @param {Object} param0.params
* @return {Promise}
*/

function getContestModerators({ username, params }) {
return new Promise((resolve, reject) => {
const { contest_id: contestId } = params
pool.query(
`SELECT username, full_name, profile_img FROM users u
INNER JOIN contests_moderators cm ON u.username = cm.moderator
WHERE EXISTS(SELECT 1 FROM contests_moderators WHERE contest_id=? AND moderator=?) AND cm.contest_id = ?`,
[contestId, username, contestId],
(error, results) => {
if (error || results === undefined) {
return reject(error)
}
if (!results || !results.length) {
return reject('The user do not have moderator access to the contest')
}
return resolve(results)
}
)
})
}

module.exports = getContestModerators
42 changes: 42 additions & 0 deletions server/models/contests/getContests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/* eslint-disable no-async-promise-executor */
const { pool } = require('../../models/database')

/**
* @param {*} param0
* @param {String} param0.username
* @param {Object} param0.query
* @return {Promise}
*/

function getContests({ username, query }) {
return new Promise((resolve, reject) => {
const { status } = query
let limit = Number(query.limit)
if (!limit) {
limit = 5
}

let sqlQuery = `SELECT id, creator, name, start_time, end_time FROM contests
WHERE (public=1 OR EXISTS(SELECT 1 FROM contests_groups cg INNER JOIN user_groups ug
ON cg.group_id = ug.group_id WHERE ug.username=?))`

if (status === 'past') {
sqlQuery += ` AND NOW() > end_time ORDER BY end_time DESC`
} else if (status === 'active') {
sqlQuery += ` AND NOW() >= start_time AND NOW() <= end_time ORDER BY start_time`
} else if (status === 'upcoming') {
sqlQuery += ` AND NOW() < start_time ORDER BY start_time`
} else {
return reject('Status required')
}
sqlQuery += ` LIMIT ?`
pool.query(sqlQuery, [username, limit], (error, results) => {
if (error || results === undefined) {
return reject(error)
}
return resolve(results)
})
})
}

module.exports = getContests
33 changes: 33 additions & 0 deletions server/models/contests/getModeratorContests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const { pool } = require('../../models/database')

/**
* @param {*} param0
* @param {String} param0.username
* @param {Object} param0.query
* @return {Promise}
*/

function getModeratorContests({ username, query }) {
return new Promise((resolve, reject) => {
const limit = Number(query.limit)
const cursor = Number(query.cursor)
let sqlQuery = `SELECT id,name,creator,start_time,end_time,participants_count,public,confidential_questions FROM contests c JOIN contests_moderators cm ON c.id=cm.contest_id WHERE cm.moderator=? `
let arr = [username]
if (cursor) {
sqlQuery += `AND c.id>? `
arr.push(cursor)
}
if (limit && limit > 0) {
sqlQuery += ` LIMIT ?`
arr.push(limit)
}
pool.query(sqlQuery, arr, (error, results) => {
if (error || results === undefined) {
return reject(error)
}
return resolve(results)
})
})
}

module.exports = getModeratorContests
16 changes: 16 additions & 0 deletions server/models/contests/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ const addModerator = require('./addModerator')
const removeModerator = require('./removeModerator')
const addGroup = require('./addGroup')
const removeGroup = require('./removeGroup')
const getContests = require('./getContests')
const getModeratorContests = require('./getModeratorContests')
const getContest = require('./getContest')
const getContestDetails = require('./getContestDetails')
const getContestModerators = require('./getContestModerators')
const participate = require('./participate')
const getAllParticipants = require('./getAllParticipants')
const getAllParticipantsDetails = require('./getAllParticipantsDetails')

module.exports = {
createContest,
Expand All @@ -12,4 +20,12 @@ module.exports = {
removeModerator,
addGroup,
removeGroup,
getContests,
getModeratorContests,
getContest,
getContestDetails,
getContestModerators,
participate,
getAllParticipants,
getAllParticipantsDetails,
}
79 changes: 79 additions & 0 deletions server/models/contests/participate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
const { pool } = require('../database')

/**
* @param {*} param0
* @param {Object} param0.params
* @param {String} param0.username
* @return {Promise}
*/

function participate({ params, username }) {
return new Promise((resolve, reject) => {
const { contest_id: contestId } = params
pool.getConnection((error, connection) => {
if (error) {
return reject(error)
}
connection.beginTransaction((error) => {
if (error) {
connection.release()
return reject(error)
}
connection.query(
`INSERT INTO contests_participants (contest_id, participant) SELECT ?, ?
WHERE (EXISTS(SELECT 1 FROM user_groups ug INNER JOIN contests_groups cg ON ug.group_id = cg.group_id WHERE ug.username=? AND cg.contest_id=?)
OR EXISTS(SELECT 1 FROM contests WHERE id=? AND public=1))
AND EXISTS(SELECT 1 FROM contests WHERE id=? AND NOW()<=end_time)`,
[contestId, username, username, contestId, contestId, contestId],
(error, res) => {
if (error || res === undefined) {
return connection.rollback(() => {
connection.release()
const { code } = error
if (code === 'ER_DUP_ENTRY') {
return reject('The user is already a participant')
}
return reject(error)
})
}
const { affectedRows } = res
if (!affectedRows) {
return connection.rollback(() => {
connection.release()
return reject(
'You are not eligible to register for the contest'
)
})
}
connection.query(
`UPDATE contests SET participants_count = participants_count + 1 WHERE id=?`,
[contestId],
(error, updateResults) => {
if (error || updateResults === undefined) {
return connection.rollback(() => {
connection.release()
return reject(error)
})
}
connection.commit((error) => {
if (error) {
return connection.rollback(() => {
connection.release()
return reject(error)
})
}
connection.release()
return resolve(
'The user successfully registered for the contest'
)
})
}
)
}
)
})
})
})
}

module.exports = participate
Loading

0 comments on commit d0f9272

Please sign in to comment.