import { UserType } from "../types/basicUser";
import IUserFilters from "../types/userFilters";
import { RequestContext } from "./requestContext";
/**
* Class for handling filters
*/
class UserFilters {
// sortBy?: "mostFollowers" | "mostContent" |
// "mostAnimations" | "mostViews" | "mostComments" | "mostPopular";
skip?: number;
limit?: number;
query?: string;
private variables: string[] = [];
private queryParts: {
select: string[],
from: string[],
where: string[],
groupBy: string[],
orderBy: string[],
limit: (string|number)[]
} = {
select: ["users.*"],
from: ["users"],
where: [],
groupBy: [],
orderBy: [],
limit: []
};
/**
* Instantiates the class
* @param {IUserFilters} data
*/
constructor(data: IUserFilters, public ctx: RequestContext) {
// this.sortBy = data.sortBy;
this.query = data.query;
}
/**
* Clones the class
* Building query modifies internal state, so we need to clone it sometimes
* @return {UserFilters}
*/
clone() {
return new UserFilters({
// sortBy: this.sortBy,
skip: this.skip,
limit: this.limit,
query: this.query
}, this.ctx);
}
/**
* Builds the query to get the count
* @return {{ query: string, variables: string[]}}
*/
buildCountQuery(): { query: string, variables: string[] } {
this.variables = [];
// this.prepareQueryOrderByPart();
this.buildQueryWherePart();
this.buildQueryLimitPart();
var query =
"SELECT COUNT(*) as count FROM (SELECT " + this.queryParts.select.join(", ") +
" FROM " + this.queryParts.from.join(", ") +
(this.queryParts.where.length ? " WHERE " + this.queryParts.where.join(" AND ") : "") +
(this.queryParts.groupBy.length ? " GROUP BY " + this.queryParts.groupBy.join(", ") : "") +
") as users";
return {
query,
variables: this.variables
};
}
/**
* Builds the query
* @return {{ query: string, variables: string[] }}
*/
buildQuery(): { query: string, variables: string[] } {
this.variables = [];
this.prepareQueryOrderByPart();
this.buildQueryWherePart();
this.buildQueryLimitPart();
var query =
`SELECT ${this.queryParts.select.join(", ")} FROM ${this.queryParts.from.join(", ")}` +
(this.queryParts.where.length ? " WHERE " + this.queryParts.where.join(" AND ") : "") +
(this.queryParts.groupBy.length ? " GROUP BY " + this.queryParts.groupBy.join(", ") : "") +
(this.queryParts.orderBy.length ? " ORDER BY " + this.queryParts.orderBy.join(", ") : "") +
(this.queryParts.limit.length ? " LIMIT " + this.queryParts.limit.join(",") : "");
return {
query,
variables: this.variables
};
}
/**
* Builds the limit part
*/
private buildQueryLimitPart() {
if(this.skip) this.queryParts.limit.push(this.skip.toString());
if(this.limit) this.queryParts.limit.push(this.limit.toString());
}
/**
* Prepares the orderBy part
*/
private prepareQueryOrderByPart() {
this.queryParts.orderBy.push("users.snowflake DESC");
}
/**
* Builds the where part of queries
*/
private buildQueryWherePart() {
if(this.query) {
this.queryParts.where.push("MATCH (name, description) AGAINST (? IN BOOLEAN MODE)");
this.queryParts.select
.push("MATCH (name, description) AGAINST (? IN BOOLEAN MODE) as score");
let q = this.query;
q = `(${q.split(" ").map((t) => t + "*").join(" ")}) ("${q.replace(/"/g, "")}")`;
this.variables.push(q);
this.variables.push(q);
this.queryParts.orderBy.unshift("score DESC");
}
if((this.ctx.user && this.ctx.user.type < UserType.MODERATOR) || !this.ctx.user) {
this.queryParts.where.push(
"type >= 0"
);
}
// TODO: blocked doesn't exist. User relations does - fix that later
// this.queryParts.where
// .push("NOT EXISTS (SELECT * FROM blocked WHERE blocked.blocked = user.id)");
}
};
export default UserFilters;
Source