forked from Cutlery/immich
closure table
This commit is contained in:
parent
683a56fc07
commit
2076e8f595
@ -12,6 +12,9 @@ import {
|
|||||||
OneToMany,
|
OneToMany,
|
||||||
PrimaryColumn,
|
PrimaryColumn,
|
||||||
PrimaryGeneratedColumn,
|
PrimaryGeneratedColumn,
|
||||||
|
Tree,
|
||||||
|
TreeChildren,
|
||||||
|
TreeParent,
|
||||||
UpdateDateColumn,
|
UpdateDateColumn,
|
||||||
} from 'typeorm';
|
} from 'typeorm';
|
||||||
|
|
||||||
@ -22,6 +25,7 @@ export enum AssetOrder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Entity('albums')
|
@Entity('albums')
|
||||||
|
@Tree('closure-table')
|
||||||
export class AlbumEntity {
|
export class AlbumEntity {
|
||||||
@PrimaryGeneratedColumn('uuid')
|
@PrimaryGeneratedColumn('uuid')
|
||||||
id!: string;
|
id!: string;
|
||||||
@ -69,6 +73,12 @@ export class AlbumEntity {
|
|||||||
|
|
||||||
@Column({ type: 'varchar', default: AssetOrder.DESC })
|
@Column({ type: 'varchar', default: AssetOrder.DESC })
|
||||||
order!: AssetOrder;
|
order!: AssetOrder;
|
||||||
|
|
||||||
|
@TreeChildren()
|
||||||
|
children!: AlbumEntity[];
|
||||||
|
|
||||||
|
@TreeParent()
|
||||||
|
parents!: AlbumEntity[];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Entity('nested_albums')
|
@Entity('nested_albums')
|
||||||
|
33
server/src/migrations/1712173905900-AddClosureAlbumTable.ts
Normal file
33
server/src/migrations/1712173905900-AddClosureAlbumTable.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class AddClosureAlbumTable1712173905900 implements MigrationInterface {
|
||||||
|
name = 'AddClosureAlbumTable1712173905900';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TABLE "albums_closure" ("id_ancestor" uuid NOT NULL, "id_descendant" uuid NOT NULL, CONSTRAINT "PK_c73b38b33bc7f8a4b2588c573f5" PRIMARY KEY ("id_ancestor", "id_descendant"))`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_a54149056a7a5da2c44d8a65c2" ON "albums_closure" ("id_ancestor") `);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_3a2f01ca9d654f90f4a2887a36" ON "albums_closure" ("id_descendant") `);
|
||||||
|
await queryRunner.query(`ALTER TABLE "albums" ADD "parentsId" uuid`);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "albums" ADD CONSTRAINT "FK_c619d16fe935e8afd5f9105f31f" FOREIGN KEY ("parentsId") REFERENCES "albums"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "albums_closure" ADD CONSTRAINT "FK_a54149056a7a5da2c44d8a65c22" FOREIGN KEY ("id_ancestor") REFERENCES "albums"("id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "albums_closure" ADD CONSTRAINT "FK_3a2f01ca9d654f90f4a2887a362" FOREIGN KEY ("id_descendant") REFERENCES "albums"("id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "albums_closure" DROP CONSTRAINT "FK_3a2f01ca9d654f90f4a2887a362"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "albums_closure" DROP CONSTRAINT "FK_a54149056a7a5da2c44d8a65c22"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "albums" DROP CONSTRAINT "FK_c619d16fe935e8afd5f9105f31f"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "albums" DROP COLUMN "parentsId"`);
|
||||||
|
await queryRunner.query(`DROP INDEX "public"."IDX_3a2f01ca9d654f90f4a2887a36"`);
|
||||||
|
await queryRunner.query(`DROP INDEX "public"."IDX_a54149056a7a5da2c44d8a65c2"`);
|
||||||
|
await queryRunner.query(`DROP TABLE "albums_closure"`);
|
||||||
|
}
|
||||||
|
}
|
@ -14,7 +14,16 @@ import {
|
|||||||
} from 'src/interfaces/album.interface';
|
} from 'src/interfaces/album.interface';
|
||||||
import { Instrumentation } from 'src/utils/instrumentation';
|
import { Instrumentation } from 'src/utils/instrumentation';
|
||||||
import { setUnion } from 'src/utils/set';
|
import { setUnion } from 'src/utils/set';
|
||||||
import { DataSource, FindOptionsOrder, FindOptionsRelations, In, IsNull, Not, Repository } from 'typeorm';
|
import {
|
||||||
|
DataSource,
|
||||||
|
FindOptionsOrder,
|
||||||
|
FindOptionsRelations,
|
||||||
|
In,
|
||||||
|
IsNull,
|
||||||
|
Not,
|
||||||
|
Repository,
|
||||||
|
TreeRepository,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
@Instrumentation()
|
@Instrumentation()
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -23,6 +32,7 @@ export class AlbumRepository implements IAlbumRepository {
|
|||||||
@InjectRepository(AssetEntity) private assetRepository: Repository<AssetEntity>,
|
@InjectRepository(AssetEntity) private assetRepository: Repository<AssetEntity>,
|
||||||
@InjectRepository(AlbumEntity) private repository: Repository<AlbumEntity>,
|
@InjectRepository(AlbumEntity) private repository: Repository<AlbumEntity>,
|
||||||
@InjectRepository(NestedAlbumEntity) private nestedAlbumRepository: Repository<NestedAlbumEntity>,
|
@InjectRepository(NestedAlbumEntity) private nestedAlbumRepository: Repository<NestedAlbumEntity>,
|
||||||
|
@InjectRepository(AlbumEntity) private albumTreeRepository: TreeRepository<AlbumEntity>,
|
||||||
@InjectDataSource() private dataSource: DataSource,
|
@InjectDataSource() private dataSource: DataSource,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@ -363,6 +373,13 @@ export class AlbumRepository implements IAlbumRepository {
|
|||||||
|
|
||||||
@GenerateSql()
|
@GenerateSql()
|
||||||
async getNestedAlbums(id: string): Promise<NestedAlbums> {
|
async getNestedAlbums(id: string): Promise<NestedAlbums> {
|
||||||
|
const album = await this.repository.findOneOrFail({ where: { id } });
|
||||||
|
const ancestor = await this.albumTreeRepository.findAncestorsTree(album);
|
||||||
|
console.log('Parents', ancestor);
|
||||||
|
console.log('-----------------');
|
||||||
|
const desc = await this.albumTreeRepository.findDescendantsTree(album);
|
||||||
|
console.log('Children', desc);
|
||||||
|
|
||||||
const children = await this.repository
|
const children = await this.repository
|
||||||
.createQueryBuilder('albums')
|
.createQueryBuilder('albums')
|
||||||
.innerJoin('nested_albums', 'nested', 'nested.childId = albums.id')
|
.innerJoin('nested_albums', 'nested', 'nested.childId = albums.id')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user