mirror of
https://github.com/immich-app/immich
synced 2026-08-15 13:03:57 +00:00
Merge d2e9f822a2 into 652ef8a427
This commit is contained in:
commit
7e5927e639
4 changed files with 103 additions and 1 deletions
|
|
@ -10,6 +10,30 @@ select
|
|||
(
|
||||
select
|
||||
"asset".*,
|
||||
(
|
||||
select
|
||||
coalesce(json_agg(agg), '[]')
|
||||
from
|
||||
(
|
||||
select
|
||||
"asset_face".*,
|
||||
"person" as "person"
|
||||
from
|
||||
"asset_face"
|
||||
left join lateral (
|
||||
select
|
||||
"person".*
|
||||
from
|
||||
"person"
|
||||
where
|
||||
"asset_face"."personId" = "person"."id"
|
||||
) as "person" on true
|
||||
where
|
||||
"asset_face"."assetId" = "asset"."id"
|
||||
and "asset_face"."deletedAt" is null
|
||||
and "asset_face"."isVisible" is true
|
||||
) as agg
|
||||
) as "faces",
|
||||
to_json("exifInfo") as "exifInfo"
|
||||
from
|
||||
"asset"
|
||||
|
|
@ -76,6 +100,30 @@ select
|
|||
(
|
||||
select
|
||||
"asset".*,
|
||||
(
|
||||
select
|
||||
coalesce(json_agg(agg), '[]')
|
||||
from
|
||||
(
|
||||
select
|
||||
"asset_face".*,
|
||||
"person" as "person"
|
||||
from
|
||||
"asset_face"
|
||||
left join lateral (
|
||||
select
|
||||
"person".*
|
||||
from
|
||||
"person"
|
||||
where
|
||||
"asset_face"."personId" = "person"."id"
|
||||
) as "person" on true
|
||||
where
|
||||
"asset_face"."assetId" = "asset"."id"
|
||||
and "asset_face"."deletedAt" is null
|
||||
and "asset_face"."isVisible" is true
|
||||
) as agg
|
||||
) as "faces",
|
||||
(
|
||||
select
|
||||
coalesce(json_agg(agg), '[]')
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import { columns } from 'src/database';
|
|||
import { DummyValue, GenerateSql } from 'src/decorators';
|
||||
import { DB } from 'src/schema';
|
||||
import { StackTable } from 'src/schema/tables/stack.table';
|
||||
import { asUuid, withDefaultVisibility } from 'src/utils/database';
|
||||
import { asUuid, withDefaultVisibility, withFacesAndPeople } from 'src/utils/database';
|
||||
|
||||
export interface StackSearch {
|
||||
ownerId: string;
|
||||
|
|
@ -27,6 +27,7 @@ const withAssets = (eb: ExpressionBuilder<DB, 'stack'>, withTags = false) => {
|
|||
.as('exifInfo'),
|
||||
(join) => join.onTrue(),
|
||||
)
|
||||
.select(withFacesAndPeople)
|
||||
.$if(withTags, (eb) =>
|
||||
eb.select((eb) =>
|
||||
jsonArrayFrom(
|
||||
|
|
|
|||
|
|
@ -203,6 +203,12 @@ export const getForStack = (stack: ReturnType<StackFactory['build']>) => ({
|
|||
assets: stack.assets.map((asset) => ({
|
||||
...getDehydrated(asset),
|
||||
exifInfo: getDehydrated(asset.exifInfo),
|
||||
faces: asset.faces
|
||||
.filter((face): face is typeof face & { person: NonNullable<typeof face.person> } => face.person !== null)
|
||||
.map((face) => ({
|
||||
...getDehydrated(face),
|
||||
person: getDehydrated(face.person),
|
||||
})),
|
||||
})),
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
import { Kysely } from 'kysely';
|
||||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||
import { StackRepository } from 'src/repositories/stack.repository';
|
||||
import { DB } from 'src/schema';
|
||||
import { BaseService } from 'src/services/base.service';
|
||||
import { newMediumService } from 'test/medium.factory';
|
||||
import { getKyselyDB } from 'test/utils';
|
||||
|
||||
let defaultDatabase: Kysely<DB>;
|
||||
|
||||
const setup = (db?: Kysely<DB>) => {
|
||||
const { ctx } = newMediumService(BaseService, {
|
||||
database: db || defaultDatabase,
|
||||
real: [],
|
||||
mock: [LoggingRepository],
|
||||
});
|
||||
return { ctx, sut: ctx.get(StackRepository) };
|
||||
};
|
||||
|
||||
beforeAll(async () => {
|
||||
defaultDatabase = await getKyselyDB();
|
||||
});
|
||||
|
||||
describe(StackRepository.name, () => {
|
||||
describe('getById', () => {
|
||||
it('should return faces for stack assets', async () => {
|
||||
const { ctx, sut } = setup();
|
||||
const { user } = await ctx.newUser();
|
||||
const { asset: primaryAsset } = await ctx.newAsset({ ownerId: user.id });
|
||||
const { asset: secondaryAsset } = await ctx.newAsset({ ownerId: user.id });
|
||||
|
||||
await ctx.newExif({ assetId: primaryAsset.id, fileSizeInByte: 123 });
|
||||
await ctx.newExif({ assetId: secondaryAsset.id, fileSizeInByte: 456 });
|
||||
|
||||
const { person } = await ctx.newPerson({ ownerId: user.id });
|
||||
await ctx.newAssetFace({ assetId: primaryAsset.id, personId: person.id });
|
||||
|
||||
const { result: createdStack } = await ctx.newStack({ ownerId: user.id }, [primaryAsset.id, secondaryAsset.id]);
|
||||
|
||||
const stack = await sut.getById(createdStack.id);
|
||||
|
||||
expect(stack).toBeDefined();
|
||||
expect(stack?.assets[0]?.faces).toHaveLength(1);
|
||||
expect(stack?.assets[0]?.faces[0]?.person?.id).toBe(person.id);
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue