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

View file

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