generic methods to lock and unlock Entities
parent
614f9a652c
commit
14b9d3445a
@ -0,0 +1,101 @@
|
||||
import { Connection, ObjectType } from 'typeorm';
|
||||
import { CargoBike, Lockable } from '../../model/CargoBike';
|
||||
|
||||
export class LockUtils {
|
||||
static getToken (req: any) : string {
|
||||
return req.headers.authorization?.replace('Bearer ', '');
|
||||
}
|
||||
|
||||
/**
|
||||
* locks any entity that implements Lockable
|
||||
*/
|
||||
static async lockEntity (connection: Connection, target: ObjectType<Lockable>, alias: string, id: number, req: any, dataSources: any) {
|
||||
const token = this.getToken(req);
|
||||
const userId = await dataSources.userAPI.getUserId(token);
|
||||
const lock = await connection.getRepository(target)
|
||||
.createQueryBuilder(alias)
|
||||
.select([
|
||||
alias + '.lockedUntil',
|
||||
alias + '.lockedBy'
|
||||
])
|
||||
.where('id = :id', {
|
||||
id: id
|
||||
})
|
||||
.andWhere(alias + '.lockedUntil > CURRENT_TIMESTAMP')
|
||||
.getOne();
|
||||
// eslint-disable-next-line eqeqeq
|
||||
if (!lock?.lockedUntil || lock?.lockedBy == userId) {
|
||||
// no lock -> set lock
|
||||
await connection.getRepository(target)
|
||||
.createQueryBuilder(alias)
|
||||
.update()
|
||||
.set({
|
||||
lockedUntil: () => 'CURRENT_TIMESTAMP + INTERVAL \'10 MINUTE\'',
|
||||
lockedBy: userId
|
||||
})
|
||||
.where('id = :id', { id: id })
|
||||
.execute();
|
||||
return true;
|
||||
} else {
|
||||
// lock was set
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static async unlockEntity (connection: Connection, target: ObjectType<Lockable>, alias: string, id: number, req: any, dataSources: any) {
|
||||
const token = this.getToken(req);
|
||||
const userId = await dataSources.userAPI.getUserId(token);
|
||||
const lock = await connection.getRepository(target)
|
||||
.createQueryBuilder(alias)
|
||||
.select([
|
||||
alias + '.lockedUntil',
|
||||
alias + '.lockedBy'
|
||||
])
|
||||
.where('id = :id', {
|
||||
id: id
|
||||
})
|
||||
.andWhere(alias + '.lockedUntil > CURRENT_TIMESTAMP')
|
||||
.getOne();
|
||||
if (!lock?.lockedUntil) {
|
||||
// no lock
|
||||
return true;
|
||||
// eslint-disable-next-line eqeqeq
|
||||
} else if (lock?.lockedBy == userId) {
|
||||
// user can unlock
|
||||
await connection.getRepository(target)
|
||||
.createQueryBuilder(alias)
|
||||
.update()
|
||||
.set({
|
||||
lockedUntil: null,
|
||||
lockedBy: null
|
||||
})
|
||||
.where('id = :id', { id: id })
|
||||
.execute();
|
||||
return true;
|
||||
} else {
|
||||
// entity is locked by other user
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static async isLocked (connection: Connection, target: ObjectType<Lockable>, alias: string, id: number, req: any, dataSources: any) {
|
||||
const token = this.getToken(req);
|
||||
const userId = await dataSources.userAPI.getUserId(token);
|
||||
const lock = await connection.getRepository(CargoBike)
|
||||
.createQueryBuilder(alias)
|
||||
.select([
|
||||
alias + '.lockedUntil',
|
||||
alias + '.lockedBy'
|
||||
])
|
||||
.where('id = :id', {
|
||||
id: id
|
||||
})
|
||||
.andWhere(alias + '.lockedUntil > CURRENT_TIMESTAMP')
|
||||
.getOne();
|
||||
if (!lock?.lockedUntil) {
|
||||
// no lock
|
||||
return false;
|
||||
// eslint-disable-next-line eqeqeq
|
||||
} else return lock?.lockedBy != userId;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue