🚧 auto delete relations

This commit is contained in:
Flam3rboy 2021-09-20 17:11:22 +02:00
parent 3c8b0f43c4
commit ce09e01c21
5 changed files with 64 additions and 19 deletions

View File

@ -1,6 +1,15 @@
import { Channel, ChannelDeleteEvent, ChannelPermissionOverwriteType, ChannelType, ChannelUpdateEvent, emitEvent, Recipient } from "@fosscord/util";
import {
Channel,
ChannelDeleteEvent,
ChannelPermissionOverwriteType,
ChannelType,
ChannelUpdateEvent,
emitEvent,
Recipient,
handleFile
} from "@fosscord/util";
import { Request, Response, Router } from "express";
import { handleFile, route } from "@fosscord/api";
import { route } from "@fosscord/api";
const router: Router = Router();
// TODO: delete channel
@ -20,15 +29,14 @@ router.delete("/", route({ permission: "MANAGE_CHANNELS" }), async (req: Request
const channel = await Channel.findOneOrFail({ where: { id: channel_id }, relations: ["recipients"] });
if (channel.type === ChannelType.DM) {
const recipient = await Recipient.findOneOrFail({ where: { channel_id: channel_id, user_id: req.user_id } })
recipient.closed = true
const recipient = await Recipient.findOneOrFail({ where: { channel_id: channel_id, user_id: req.user_id } });
recipient.closed = true;
await Promise.all([
recipient.save(),
emitEvent({ event: "CHANNEL_DELETE", data: channel, user_id: req.user_id } as ChannelDeleteEvent)
]);
} else if (channel.type === ChannelType.GROUP_DM) {
await Channel.removeRecipientFromChannel(channel, req.user_id)
await Channel.removeRecipientFromChannel(channel, req.user_id);
} else {
//TODO messages in this channel should be deleted before deleting the channel
await Promise.all([

BIN
util/package-lock.json generated

Binary file not shown.

View File

@ -1,5 +1,14 @@
import "reflect-metadata";
import { BaseEntity, BeforeInsert, BeforeUpdate, EntityMetadata, FindConditions, PrimaryColumn } from "typeorm";
import {
BaseEntity,
BeforeInsert,
BeforeUpdate,
EntityMetadata,
FindConditions,
getConnection,
PrimaryColumn,
RemoveOptions,
} from "typeorm";
import { Snowflake } from "../util/Snowflake";
import "missing-native-js-functions";
@ -69,6 +78,44 @@ export class BaseClassWithoutId extends BaseEntity {
const repository = this.getRepository();
return repository.decrement(conditions, propertyPath, value);
}
static async delete<T>(criteria: FindConditions<T>, options?: RemoveOptions) {
if (!criteria) throw new Error("You need to specify delete criteria");
const repository = this.getRepository();
const promises = repository.metadata.relations.map((x) => {
if (x.orphanedRowAction !== "delete") return;
if (typeof x.type === "string") return;
const foreignKey =
x.foreignKeys.find((key) => key.entityMetadata === repository.metadata) ||
x.inverseRelation?.foreignKeys[0]; // find foreign key for this entity
if (!foreignKey) {
throw new Error(
`Foreign key not found for entity ${repository.metadata.name} in relation ${x.propertyName}`
);
}
console.log(foreignKey);
const id = (criteria as any)[foreignKey.referencedColumnNames[0]];
if (!id) throw new Error("id missing in criteria options");
if (x.relationType === "many-to-many" || x.relationType === "one-to-many") {
return getConnection()
.createQueryBuilder()
.relation(this, x.propertyName)
.of(id)
.remove({ [foreignKey.columnNames[0]]: id });
} else if (x.relationType === "one-to-one" || x.relationType === "many-to-one") {
return getConnection()
.createQueryBuilder()
.from(x.inverseEntityMetadata, "user")
.of(id)
.remove({ [foreignKey.name]: id });
}
});
await Promise.all(promises);
return super.delete(criteria, options);
}
}
export class BaseClass extends BaseClassWithoutId {

View File

@ -1,14 +1,4 @@
import {
Column,
Entity,
FindConditions,
JoinColumn,
ManyToOne,
ObjectID,
OneToMany,
RelationId,
RemoveOptions,
} from "typeorm";
import { Column, Entity, JoinColumn, ManyToOne, OneToMany, RelationId } from "typeorm";
import { BaseClass } from "./BaseClass";
import { Guild } from "./Guild";
import { PublicUserProjection, User } from "./User";

View File

@ -21,7 +21,7 @@ export function initDatabase() {
//
entities: Object.values(Models).filter((x) => x.constructor.name !== "Object"),
synchronize: true,
logging: false,
logging: true,
cache: {
duration: 1000 * 3, // cache all find queries for 3 seconds
},