refactor(server): introduce scoped query builders for recurring filters

This commit is contained in:
Julian Tölle 2020-07-12 14:47:32 +02:00
parent 1b03bacb7b
commit 11af91cadb
3 changed files with 41 additions and 23 deletions

View file

@ -1,5 +1,35 @@
import { EntityRepository, Repository } from "typeorm";
// tslint:disable: max-classes-per-file
import { EntityRepository, Repository, SelectQueryBuilder } from "typeorm";
import { User } from "../users/user.entity";
import { Listen } from "./listen.entity";
import { Interval } from "../reports/interval";
export class ListenScopes extends SelectQueryBuilder<Listen> {
/**
* `byUser` scopes the query to listens created by the user.
* @param currentUser
*/
byUser(currentUser: User): this {
return this.andWhere(`listen."userId" = :userID`, {
userID: currentUser.id,
});
}
/**
* `duringInterval` scopes the query to listens played during the interval.
* @param interval
*/
duringInterval(interval: Interval): this {
return this.andWhere("listen.playedAt BETWEEN :timeStart AND :timeEnd", {
timeStart: interval.start,
timeEnd: interval.end,
});
}
}
@EntityRepository(Listen)
export class ListenRepository extends Repository<Listen> {}
export class ListenRepository extends Repository<Listen> {
get scoped(): ListenScopes {
return new ListenScopes(this.createQueryBuilder("listen"));
}
}

View file

@ -45,25 +45,17 @@ export class ListensService {
): Promise<Pagination<Listen>> {
const { page, limit, user, filter } = options;
let queryBuilder = this.listenRepository
.createQueryBuilder("l")
.leftJoin("l.user", "user")
.where("user.id = :userID", { userID: user.id })
.leftJoinAndSelect("l.track", "track")
let queryBuilder = this.listenRepository.scoped
.byUser(user)
.leftJoinAndSelect("listen.track", "track")
.leftJoinAndSelect("track.artists", "artists")
.leftJoinAndSelect("track.album", "album")
.leftJoinAndSelect("album.artists", "albumArtists")
.orderBy("l.playedAt", "DESC");
.orderBy("listen.playedAt", "DESC");
if (filter) {
if (filter.time) {
queryBuilder = queryBuilder.andWhere(
"l.playedAt BETWEEN :timeStart AND :timeEnd",
{
timeStart: filter.time.start,
timeEnd: filter.time.end,
}
);
queryBuilder = queryBuilder.duringInterval(filter.time);
}
}

View file

@ -112,14 +112,10 @@ export class ReportsService {
customTimeEnd,
});
const getArtistsWithCountQB = this.listenRepository
.createQueryBuilder("l")
.andWhere('l."userId" = :userID', { userID: user.id })
.andWhere("l.playedAt BETWEEN :timeStart AND :timeEnd", {
timeStart: interval.start,
timeEnd: interval.end,
})
.leftJoin("l.track", "track")
const getArtistsWithCountQB = this.listenRepository.scoped
.byUser(user)
.duringInterval(interval)
.leftJoin("listen.track", "track")
.leftJoinAndSelect("track.artists", "artists")
.groupBy("artists.id")
.select("artists.*")