fix(permissions): remove composite primary keys

TypeORM promises to support composite primary keys,
but that does not work in reality.
This replaces the composite key used in the permission entities with
a single generated primary key and
a unique index on the relation columns.

See https://github.com/typeorm/typeorm/issues/8513

Signed-off-by: David Mehren <git@herrmehren.de>
This commit is contained in:
David Mehren 2022-09-18 18:24:27 +02:00
parent 2689f9f3dc
commit d1c3058655
7 changed files with 199 additions and 143 deletions

View file

@ -3,35 +3,34 @@
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { Column, Entity, ManyToOne, PrimaryColumn } from 'typeorm';
import {
Column,
Entity,
Index,
ManyToOne,
PrimaryGeneratedColumn,
} from 'typeorm';
import { Group } from '../groups/group.entity';
import { Note } from '../notes/note.entity';
@Entity()
@Index(['group', 'note'], { unique: true })
export class NoteGroupPermission {
/**
* The `group` and `note` properties cannot be converted to promises
* (to lazy-load them), as TypeORM gets confused about lazy composite
* primary keys.
* See https://github.com/typeorm/typeorm/issues/6908
*/
@PrimaryColumn()
groupId: number;
@PrimaryGeneratedColumn()
id: number;
@ManyToOne((_) => Group, {
onDelete: 'CASCADE', // This deletes the NoteGroupPermission, when the associated Group is deleted
orphanedRowAction: 'delete', // This ensures the whole row is deleted when the Permission stops being referenced
})
group: Group;
@PrimaryColumn()
noteId: number;
group: Promise<Group>;
@ManyToOne((_) => Note, (note) => note.groupPermissions, {
onDelete: 'CASCADE', // This deletes the NoteGroupPermission, when the associated Note is deleted
orphanedRowAction: 'delete', // This ensures the whole row is deleted when the Permission stops being referenced
})
note: Note;
note: Promise<Note>;
@Column()
canEdit: boolean;
@ -45,8 +44,8 @@ export class NoteGroupPermission {
canEdit: boolean,
): NoteGroupPermission {
const groupPermission = new NoteGroupPermission();
groupPermission.group = group;
groupPermission.note = note;
groupPermission.group = Promise.resolve(group);
groupPermission.note = Promise.resolve(note);
groupPermission.canEdit = canEdit;
return groupPermission;
}