import { RequestContext } from "./requestContext";
/**
* Class for handling tickets
*/
export class Ticket {
/**
* Verifies and uses a ticket. If the ticket is invalid, an error is thrown.
* @param {RequestContext} ctx
* @param {string} ticket
* @return {Promise<void>}
*/
public static verifyAndUse(ctx: RequestContext, ticket: string): Promise<void> {
return new Promise((resolve, reject) => {
ctx.conn.getConnection((err, conn) => {
if(err) return reject(err);
conn.beginTransaction((err) => {
if(err) {
conn.release();
return reject(err);
}
conn.query("SELECT * FROM tickets WHERE name = ? FOR UPDATE", [ticket],
(err, results) => {
if(!results || !results.length || err) {
return conn.rollback(() => {
reject(err || new Error("Ticket not found"));
conn.release();
});
}
const ticket = results[0];
if(ticket.usages + 1 >= ticket.max_usages) {
return conn.rollback(() => {
reject(new Error("Ticket has been used too many times"));
conn.release();
});
}
conn.query("UPDATE tickets SET usages = usages + 1 WHERE name = ?",
[ticket.name], (err) => {
if(err) {
return conn.rollback(() => {
reject(err);
conn.release();
});
}
conn.commit((err) => {
if(err) {
return conn.rollback(() => {
reject(err);
conn.release();
});
}
conn.release();
resolve();
});
});
});
});
});
});
}
}
Source