import Snowflake from "./snowflake";
import UserClient from "./userClient";
import { SnowflakeString } from "../types/snowflake";
import { UserType } from "../types/basicUser";
import Collection from "@discordjs/collection";
import { RequestContext } from "./requestContext";
import { DBCategory, prisma } from "../../prisma";
const cache = new Collection<SnowflakeString, Category>();
let lengthCache = -1;
/**
* Holds data about given category
*/
class Category {
id: Snowflake;
ctx: RequestContext;
client?: UserClient;
name: string;
description: string;
/**
* @param {object} data
*/
constructor({
id,
ctx,
name,
description
}: {
id: Snowflake,
ctx: RequestContext,
name: string,
description: string
}) {
this.id = id;
this.ctx = ctx;
this.client = ctx.client;
this.name = name;
this.description = description;
}
/**
* @param {DBCategory} data
* @param {RequestContext} ctx
* @return {Category}
*/
static fromDatabase(data: DBCategory, ctx: RequestContext): Category {
if(cache.has(data.snowflake.toString())) {
return cache.get(data.snowflake.toString()) as Category;
}
const cat = new Category({
id: new Snowflake(data.snowflake),
ctx,
name: data.name,
description: data.description
});
cache.set(data.snowflake.toString(), cat);
return cat;
}
/**
* Fetches category by id
* @param {bigint | Snowflake | SnowflakeString} id
* @param {requestContext} ctx
* @param {UserClient | undefined} client
* @return {Promise<Category>}
*/
static async getCategory(id: bigint | Snowflake | SnowflakeString, ctx: RequestContext):
Promise<Category> {
let b: bigint;
if(typeof id === "bigint") b = id;
else if(id instanceof Snowflake) b = id.toBigInt();
else b = BigInt(id);
if(cache.has(id.toString())) return cache.get(id.toString()) as Category;
const data = await prisma.category.findUniqueOrThrow({
where: {
snowflake: b
}
});
return Category.fromDatabase(data, ctx);
}
/**
* Gets total number of categories
* @param {RequestContext} ctx
* @return {Promise<number>}
*/
static async getCategoryCount(ctx: RequestContext): Promise<number> {
if(lengthCache !== -1) return lengthCache;
const length = await prisma.category.count();
lengthCache = length;
return length;
}
/**
* Gets categories
* @param {RequestContext} ctx
* @param {number} max
* @param {number} page
* @param {UserClient?} client
* @return {Promise<Collection<SnowflakeString, Category>>}
*/
static async getCategories(ctx: RequestContext, max: number, page: number):
Promise<Collection<SnowflakeString, Category>> {
if(lengthCache < max && cache.size === lengthCache && page === 0) return cache;
const categories = await prisma.category.findMany({
skip: page*max,
take: max
});
const col = new Collection<SnowflakeString, Category>();
for(const category of categories) {
col.set(category.snowflake.toString(), Category.fromDatabase(category, ctx));
}
return col;
}
/**
* Updates the given category
* @return {Promise<void>}
*/
async update(): Promise<void> {
if(!this.client) throw new Error("unauthorized");
if(!this.client.user.comparePosition(UserType.MODERATOR)) {
throw new Error("unauthorized");
}
await prisma.category.update({
where: {
snowflake: this.id.toBigInt()
},
data: {
name: this.name,
description: this.description
}
});
}
/**
* Creates a JSON-compatible object
* @return {Object}
*/
toJSON() {
return {
id: this.id.getSnowflake(),
name: this.name,
description: this.description
};
}
}
export default Category;
Source