forked from Cutlery/immich
		
	better relationship
This commit is contained in:
		
							parent
							
								
									0d1c45316c
								
							
						
					
					
						commit
						ca06105d00
					
				@ -163,16 +163,6 @@ export const mapAlbum = (entity: AlbumEntity, withAssets: boolean, auth?: AuthDt
 | 
				
			|||||||
    assetCount: entity.assets?.length || 0,
 | 
					    assetCount: entity.assets?.length || 0,
 | 
				
			||||||
    isActivityEnabled: entity.isActivityEnabled,
 | 
					    isActivityEnabled: entity.isActivityEnabled,
 | 
				
			||||||
    order: entity.order,
 | 
					    order: entity.order,
 | 
				
			||||||
    parentAlbums: entity.parentAlbums?.map((album) => ({
 | 
					 | 
				
			||||||
      id: album.id,
 | 
					 | 
				
			||||||
      albumName: album.albumName,
 | 
					 | 
				
			||||||
      albumThumbnailAssetId: album.albumThumbnailAssetId,
 | 
					 | 
				
			||||||
    })),
 | 
					 | 
				
			||||||
    childAlbums: entity.childAlbums?.map((album) => ({
 | 
					 | 
				
			||||||
      id: album.id,
 | 
					 | 
				
			||||||
      albumName: album.albumName,
 | 
					 | 
				
			||||||
      albumThumbnailAssetId: album.albumThumbnailAssetId,
 | 
					 | 
				
			||||||
    })),
 | 
					 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -69,37 +69,13 @@ export class AlbumEntity {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  @Column({ type: 'varchar', default: AssetOrder.DESC })
 | 
					  @Column({ type: 'varchar', default: AssetOrder.DESC })
 | 
				
			||||||
  order!: AssetOrder;
 | 
					  order!: AssetOrder;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  @ManyToMany(() => AlbumEntity, (album) => album.parentAlbums)
 | 
					 | 
				
			||||||
  @JoinTable({
 | 
					 | 
				
			||||||
    name: 'sub_albums',
 | 
					 | 
				
			||||||
    joinColumn: { name: 'childId' },
 | 
					 | 
				
			||||||
    inverseJoinColumn: { name: 'parentId' },
 | 
					 | 
				
			||||||
    synchronize: false,
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
  parentAlbums!: AlbumEntity[];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @ManyToMany(() => AlbumEntity, (album) => album.childAlbums)
 | 
					 | 
				
			||||||
  @JoinTable({
 | 
					 | 
				
			||||||
    name: 'sub_albums',
 | 
					 | 
				
			||||||
    joinColumn: { name: 'parentId' },
 | 
					 | 
				
			||||||
    inverseJoinColumn: { name: 'childId' },
 | 
					 | 
				
			||||||
    synchronize: false,
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
  childAlbums!: AlbumEntity[];
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Entity('sub_albums', { synchronize: false })
 | 
					@Entity('nested_albums')
 | 
				
			||||||
export class SubAlbumEntity {
 | 
					export class NestedAlbumEntity {
 | 
				
			||||||
  @PrimaryColumn()
 | 
					  @PrimaryColumn()
 | 
				
			||||||
  parentId!: string;
 | 
					  parentId!: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @PrimaryColumn()
 | 
					  @PrimaryColumn()
 | 
				
			||||||
  childId!: string;
 | 
					  childId!: string;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  @ManyToOne(() => AlbumEntity, (album) => album.childAlbums, { onDelete: 'CASCADE' })
 | 
					 | 
				
			||||||
  parent!: AlbumEntity;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @ManyToOne(() => AlbumEntity, (album) => album.parentAlbums, { onDelete: 'CASCADE' })
 | 
					 | 
				
			||||||
  child!: AlbumEntity;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import { ActivityEntity } from 'src/entities/activity.entity';
 | 
					import { ActivityEntity } from 'src/entities/activity.entity';
 | 
				
			||||||
import { AlbumEntity, SubAlbumEntity } from 'src/entities/album.entity';
 | 
					import { AlbumEntity, NestedAlbumEntity } from 'src/entities/album.entity';
 | 
				
			||||||
import { APIKeyEntity } from 'src/entities/api-key.entity';
 | 
					import { APIKeyEntity } from 'src/entities/api-key.entity';
 | 
				
			||||||
import { AssetFaceEntity } from 'src/entities/asset-face.entity';
 | 
					import { AssetFaceEntity } from 'src/entities/asset-face.entity';
 | 
				
			||||||
import { AssetJobStatusEntity } from 'src/entities/asset-job-status.entity';
 | 
					import { AssetJobStatusEntity } from 'src/entities/asset-job-status.entity';
 | 
				
			||||||
@ -40,7 +40,7 @@ export const entities = [
 | 
				
			|||||||
  SharedLinkEntity,
 | 
					  SharedLinkEntity,
 | 
				
			||||||
  SmartInfoEntity,
 | 
					  SmartInfoEntity,
 | 
				
			||||||
  SmartSearchEntity,
 | 
					  SmartSearchEntity,
 | 
				
			||||||
  SubAlbumEntity,
 | 
					  NestedAlbumEntity,
 | 
				
			||||||
  SystemConfigEntity,
 | 
					  SystemConfigEntity,
 | 
				
			||||||
  SystemMetadataEntity,
 | 
					  SystemMetadataEntity,
 | 
				
			||||||
  TagEntity,
 | 
					  TagEntity,
 | 
				
			||||||
 | 
				
			|||||||
@ -1,22 +0,0 @@
 | 
				
			|||||||
import { MigrationInterface, QueryRunner } from "typeorm";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export class AddNestedAlbumRelationship1712119327240 implements MigrationInterface {
 | 
					 | 
				
			||||||
    name = 'AddNestedAlbumRelationship1712119327240'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public async up(queryRunner: QueryRunner): Promise<void> {
 | 
					 | 
				
			||||||
        await queryRunner.query(`CREATE TABLE "sub_albums" ("parentId" uuid NOT NULL, "childId" uuid NOT NULL, CONSTRAINT "PK_bd5df025a7a641b10bce219dc8d" PRIMARY KEY ("parentId", "childId"))`);
 | 
					 | 
				
			||||||
        await queryRunner.query(`CREATE INDEX "IDX_b0b854d4c62ed6a4a46cff3b6b" ON "sub_albums" ("childId") `);
 | 
					 | 
				
			||||||
        await queryRunner.query(`CREATE INDEX "IDX_6aa094f6f0d888c90c418a14d7" ON "sub_albums" ("parentId") `);
 | 
					 | 
				
			||||||
        await queryRunner.query(`ALTER TABLE "sub_albums" ADD CONSTRAINT "FK_6aa094f6f0d888c90c418a14d70" FOREIGN KEY ("parentId") REFERENCES "albums"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
 | 
					 | 
				
			||||||
        await queryRunner.query(`ALTER TABLE "sub_albums" ADD CONSTRAINT "FK_b0b854d4c62ed6a4a46cff3b6b9" FOREIGN KEY ("childId") REFERENCES "albums"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public async down(queryRunner: QueryRunner): Promise<void> {
 | 
					 | 
				
			||||||
        await queryRunner.query(`ALTER TABLE "sub_albums" DROP CONSTRAINT "FK_b0b854d4c62ed6a4a46cff3b6b9"`);
 | 
					 | 
				
			||||||
        await queryRunner.query(`ALTER TABLE "sub_albums" DROP CONSTRAINT "FK_6aa094f6f0d888c90c418a14d70"`);
 | 
					 | 
				
			||||||
        await queryRunner.query(`DROP INDEX "public"."IDX_6aa094f6f0d888c90c418a14d7"`);
 | 
					 | 
				
			||||||
        await queryRunner.query(`DROP INDEX "public"."IDX_b0b854d4c62ed6a4a46cff3b6b"`);
 | 
					 | 
				
			||||||
        await queryRunner.query(`DROP TABLE "sub_albums"`);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										14
									
								
								server/src/migrations/1712155807366-AddNestedAlbumTable.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								server/src/migrations/1712155807366-AddNestedAlbumTable.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					import { MigrationInterface, QueryRunner } from "typeorm";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class AddNestedAlbumTable1712155807366 implements MigrationInterface {
 | 
				
			||||||
 | 
					    name = 'AddNestedAlbumTable1712155807366'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public async up(queryRunner: QueryRunner): Promise<void> {
 | 
				
			||||||
 | 
					        await queryRunner.query(`CREATE TABLE "nested_albums" ("parentId" character varying NOT NULL, "childId" character varying NOT NULL, CONSTRAINT "PK_702e1e5d9ed4b85d3bdffc934bd" PRIMARY KEY ("parentId", "childId"))`);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public async down(queryRunner: QueryRunner): Promise<void> {
 | 
				
			||||||
 | 
					        await queryRunner.query(`DROP TABLE "nested_albums"`);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -59,27 +59,7 @@ FROM
 | 
				
			|||||||
      "AlbumEntity__AlbumEntity_sharedLinks"."allowUpload" AS "AlbumEntity__AlbumEntity_sharedLinks_allowUpload",
 | 
					      "AlbumEntity__AlbumEntity_sharedLinks"."allowUpload" AS "AlbumEntity__AlbumEntity_sharedLinks_allowUpload",
 | 
				
			||||||
      "AlbumEntity__AlbumEntity_sharedLinks"."allowDownload" AS "AlbumEntity__AlbumEntity_sharedLinks_allowDownload",
 | 
					      "AlbumEntity__AlbumEntity_sharedLinks"."allowDownload" AS "AlbumEntity__AlbumEntity_sharedLinks_allowDownload",
 | 
				
			||||||
      "AlbumEntity__AlbumEntity_sharedLinks"."showExif" AS "AlbumEntity__AlbumEntity_sharedLinks_showExif",
 | 
					      "AlbumEntity__AlbumEntity_sharedLinks"."showExif" AS "AlbumEntity__AlbumEntity_sharedLinks_showExif",
 | 
				
			||||||
      "AlbumEntity__AlbumEntity_sharedLinks"."albumId" AS "AlbumEntity__AlbumEntity_sharedLinks_albumId",
 | 
					      "AlbumEntity__AlbumEntity_sharedLinks"."albumId" AS "AlbumEntity__AlbumEntity_sharedLinks_albumId"
 | 
				
			||||||
      "AlbumEntity__AlbumEntity_parentAlbums"."id" AS "AlbumEntity__AlbumEntity_parentAlbums_id",
 | 
					 | 
				
			||||||
      "AlbumEntity__AlbumEntity_parentAlbums"."ownerId" AS "AlbumEntity__AlbumEntity_parentAlbums_ownerId",
 | 
					 | 
				
			||||||
      "AlbumEntity__AlbumEntity_parentAlbums"."albumName" AS "AlbumEntity__AlbumEntity_parentAlbums_albumName",
 | 
					 | 
				
			||||||
      "AlbumEntity__AlbumEntity_parentAlbums"."description" AS "AlbumEntity__AlbumEntity_parentAlbums_description",
 | 
					 | 
				
			||||||
      "AlbumEntity__AlbumEntity_parentAlbums"."createdAt" AS "AlbumEntity__AlbumEntity_parentAlbums_createdAt",
 | 
					 | 
				
			||||||
      "AlbumEntity__AlbumEntity_parentAlbums"."updatedAt" AS "AlbumEntity__AlbumEntity_parentAlbums_updatedAt",
 | 
					 | 
				
			||||||
      "AlbumEntity__AlbumEntity_parentAlbums"."deletedAt" AS "AlbumEntity__AlbumEntity_parentAlbums_deletedAt",
 | 
					 | 
				
			||||||
      "AlbumEntity__AlbumEntity_parentAlbums"."albumThumbnailAssetId" AS "AlbumEntity__AlbumEntity_parentAlbums_albumThumbnailAssetId",
 | 
					 | 
				
			||||||
      "AlbumEntity__AlbumEntity_parentAlbums"."isActivityEnabled" AS "AlbumEntity__AlbumEntity_parentAlbums_isActivityEnabled",
 | 
					 | 
				
			||||||
      "AlbumEntity__AlbumEntity_parentAlbums"."order" AS "AlbumEntity__AlbumEntity_parentAlbums_order",
 | 
					 | 
				
			||||||
      "AlbumEntity__AlbumEntity_childAlbums"."id" AS "AlbumEntity__AlbumEntity_childAlbums_id",
 | 
					 | 
				
			||||||
      "AlbumEntity__AlbumEntity_childAlbums"."ownerId" AS "AlbumEntity__AlbumEntity_childAlbums_ownerId",
 | 
					 | 
				
			||||||
      "AlbumEntity__AlbumEntity_childAlbums"."albumName" AS "AlbumEntity__AlbumEntity_childAlbums_albumName",
 | 
					 | 
				
			||||||
      "AlbumEntity__AlbumEntity_childAlbums"."description" AS "AlbumEntity__AlbumEntity_childAlbums_description",
 | 
					 | 
				
			||||||
      "AlbumEntity__AlbumEntity_childAlbums"."createdAt" AS "AlbumEntity__AlbumEntity_childAlbums_createdAt",
 | 
					 | 
				
			||||||
      "AlbumEntity__AlbumEntity_childAlbums"."updatedAt" AS "AlbumEntity__AlbumEntity_childAlbums_updatedAt",
 | 
					 | 
				
			||||||
      "AlbumEntity__AlbumEntity_childAlbums"."deletedAt" AS "AlbumEntity__AlbumEntity_childAlbums_deletedAt",
 | 
					 | 
				
			||||||
      "AlbumEntity__AlbumEntity_childAlbums"."albumThumbnailAssetId" AS "AlbumEntity__AlbumEntity_childAlbums_albumThumbnailAssetId",
 | 
					 | 
				
			||||||
      "AlbumEntity__AlbumEntity_childAlbums"."isActivityEnabled" AS "AlbumEntity__AlbumEntity_childAlbums_isActivityEnabled",
 | 
					 | 
				
			||||||
      "AlbumEntity__AlbumEntity_childAlbums"."order" AS "AlbumEntity__AlbumEntity_childAlbums_order"
 | 
					 | 
				
			||||||
    FROM
 | 
					    FROM
 | 
				
			||||||
      "albums" "AlbumEntity"
 | 
					      "albums" "AlbumEntity"
 | 
				
			||||||
      LEFT JOIN "users" "AlbumEntity__AlbumEntity_owner" ON "AlbumEntity__AlbumEntity_owner"."id" = "AlbumEntity"."ownerId"
 | 
					      LEFT JOIN "users" "AlbumEntity__AlbumEntity_owner" ON "AlbumEntity__AlbumEntity_owner"."id" = "AlbumEntity"."ownerId"
 | 
				
			||||||
@ -92,16 +72,6 @@ FROM
 | 
				
			|||||||
        "AlbumEntity__AlbumEntity_sharedUsers"."deletedAt" IS NULL
 | 
					        "AlbumEntity__AlbumEntity_sharedUsers"."deletedAt" IS NULL
 | 
				
			||||||
      )
 | 
					      )
 | 
				
			||||||
      LEFT JOIN "shared_links" "AlbumEntity__AlbumEntity_sharedLinks" ON "AlbumEntity__AlbumEntity_sharedLinks"."albumId" = "AlbumEntity"."id"
 | 
					      LEFT JOIN "shared_links" "AlbumEntity__AlbumEntity_sharedLinks" ON "AlbumEntity__AlbumEntity_sharedLinks"."albumId" = "AlbumEntity"."id"
 | 
				
			||||||
      LEFT JOIN "sub_albums" "AlbumEntity_AlbumEntity__AlbumEntity_parentAlbums" ON "AlbumEntity_AlbumEntity__AlbumEntity_parentAlbums"."childId" = "AlbumEntity"."id"
 | 
					 | 
				
			||||||
      LEFT JOIN "albums" "AlbumEntity__AlbumEntity_parentAlbums" ON "AlbumEntity__AlbumEntity_parentAlbums"."id" = "AlbumEntity_AlbumEntity__AlbumEntity_parentAlbums"."parentId"
 | 
					 | 
				
			||||||
      AND (
 | 
					 | 
				
			||||||
        "AlbumEntity__AlbumEntity_parentAlbums"."deletedAt" IS NULL
 | 
					 | 
				
			||||||
      )
 | 
					 | 
				
			||||||
      LEFT JOIN "sub_albums" "AlbumEntity_AlbumEntity__AlbumEntity_childAlbums" ON "AlbumEntity_AlbumEntity__AlbumEntity_childAlbums"."parentId" = "AlbumEntity"."id"
 | 
					 | 
				
			||||||
      LEFT JOIN "albums" "AlbumEntity__AlbumEntity_childAlbums" ON "AlbumEntity__AlbumEntity_childAlbums"."id" = "AlbumEntity_AlbumEntity__AlbumEntity_childAlbums"."childId"
 | 
					 | 
				
			||||||
      AND (
 | 
					 | 
				
			||||||
        "AlbumEntity__AlbumEntity_childAlbums"."deletedAt" IS NULL
 | 
					 | 
				
			||||||
      )
 | 
					 | 
				
			||||||
    WHERE
 | 
					    WHERE
 | 
				
			||||||
      ((("AlbumEntity"."id" = $1)))
 | 
					      ((("AlbumEntity"."id" = $1)))
 | 
				
			||||||
      AND ("AlbumEntity"."deletedAt" IS NULL)
 | 
					      AND ("AlbumEntity"."deletedAt" IS NULL)
 | 
				
			||||||
 | 
				
			|||||||
@ -3,7 +3,7 @@ import { InjectDataSource, InjectRepository } from '@nestjs/typeorm';
 | 
				
			|||||||
import _ from 'lodash';
 | 
					import _ from 'lodash';
 | 
				
			||||||
import { dataSource } from 'src/database.config';
 | 
					import { dataSource } from 'src/database.config';
 | 
				
			||||||
import { Chunked, ChunkedArray, DATABASE_PARAMETER_CHUNK_SIZE, DummyValue, GenerateSql } from 'src/decorators';
 | 
					import { Chunked, ChunkedArray, DATABASE_PARAMETER_CHUNK_SIZE, DummyValue, GenerateSql } from 'src/decorators';
 | 
				
			||||||
import { AlbumEntity, SubAlbumEntity } from 'src/entities/album.entity';
 | 
					import { AlbumEntity } from 'src/entities/album.entity';
 | 
				
			||||||
import { AssetEntity } from 'src/entities/asset.entity';
 | 
					import { AssetEntity } from 'src/entities/asset.entity';
 | 
				
			||||||
import { AlbumAsset, AlbumAssetCount, AlbumInfoOptions, IAlbumRepository } from 'src/interfaces/album.interface';
 | 
					import { AlbumAsset, AlbumAssetCount, AlbumInfoOptions, IAlbumRepository } from 'src/interfaces/album.interface';
 | 
				
			||||||
import { Instrumentation } from 'src/utils/instrumentation';
 | 
					import { Instrumentation } from 'src/utils/instrumentation';
 | 
				
			||||||
@ -16,7 +16,6 @@ export class AlbumRepository implements IAlbumRepository {
 | 
				
			|||||||
  constructor(
 | 
					  constructor(
 | 
				
			||||||
    @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(SubAlbumEntity) private subAlbumRepository: Repository<SubAlbumEntity>,
 | 
					 | 
				
			||||||
    @InjectDataSource() private dataSource: DataSource,
 | 
					    @InjectDataSource() private dataSource: DataSource,
 | 
				
			||||||
  ) {}
 | 
					  ) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -27,8 +26,6 @@ export class AlbumRepository implements IAlbumRepository {
 | 
				
			|||||||
      sharedUsers: true,
 | 
					      sharedUsers: true,
 | 
				
			||||||
      assets: false,
 | 
					      assets: false,
 | 
				
			||||||
      sharedLinks: true,
 | 
					      sharedLinks: true,
 | 
				
			||||||
      parentAlbums: true,
 | 
					 | 
				
			||||||
      childAlbums: true,
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const order: FindOptionsOrder<AlbumEntity> = {};
 | 
					    const order: FindOptionsOrder<AlbumEntity> = {};
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user