mirror of
https://github.com/immich-app/immich
synced 2025-11-14 17:36:12 +00:00
feat(server): add memories statistics resource (#19035)
This commit is contained in:
parent
16745e77d4
commit
e88bd74fd2
12 changed files with 352 additions and 17 deletions
|
|
@ -2,7 +2,13 @@ import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put,
|
|||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { BulkIdResponseDto, BulkIdsDto } from 'src/dtos/asset-ids.response.dto';
|
||||
import { AuthDto } from 'src/dtos/auth.dto';
|
||||
import { MemoryCreateDto, MemoryResponseDto, MemorySearchDto, MemoryUpdateDto } from 'src/dtos/memory.dto';
|
||||
import {
|
||||
MemoryCreateDto,
|
||||
MemoryResponseDto,
|
||||
MemorySearchDto,
|
||||
MemoryStatisticsResponseDto,
|
||||
MemoryUpdateDto,
|
||||
} from 'src/dtos/memory.dto';
|
||||
import { Permission } from 'src/enum';
|
||||
import { Auth, Authenticated } from 'src/middleware/auth.guard';
|
||||
import { MemoryService } from 'src/services/memory.service';
|
||||
|
|
@ -25,6 +31,12 @@ export class MemoryController {
|
|||
return this.service.create(auth, dto);
|
||||
}
|
||||
|
||||
@Get('statistics')
|
||||
@Authenticated({ permission: Permission.MEMORY_READ })
|
||||
memoriesStatistics(@Auth() auth: AuthDto, @Query() dto: MemorySearchDto): Promise<MemoryStatisticsResponseDto> {
|
||||
return this.service.statistics(auth, dto);
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@Authenticated({ permission: Permission.MEMORY_READ })
|
||||
getMemory(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<MemoryResponseDto> {
|
||||
|
|
|
|||
|
|
@ -71,6 +71,11 @@ export class MemoryCreateDto extends MemoryBaseDto {
|
|||
assetIds?: string[];
|
||||
}
|
||||
|
||||
export class MemoryStatisticsResponseDto {
|
||||
@ApiProperty({ type: 'integer' })
|
||||
total!: number;
|
||||
}
|
||||
|
||||
export class MemoryResponseDto {
|
||||
id!: string;
|
||||
createdAt!: Date;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,33 @@
|
|||
-- NOTE: This file is auto generated by ./sql-generator
|
||||
|
||||
-- MemoryRepository.statistics
|
||||
select
|
||||
count(*) as "total"
|
||||
from
|
||||
"memories"
|
||||
where
|
||||
"deletedAt" is null
|
||||
and "ownerId" = $1
|
||||
|
||||
-- MemoryRepository.statistics (date filter)
|
||||
select
|
||||
count(*) as "total"
|
||||
from
|
||||
"memories"
|
||||
where
|
||||
(
|
||||
"showAt" is null
|
||||
or "showAt" <= $1
|
||||
)
|
||||
and (
|
||||
"hideAt" is null
|
||||
or "hideAt" >= $2
|
||||
)
|
||||
and "deletedAt" is null
|
||||
and "ownerId" = $3
|
||||
|
||||
-- MemoryRepository.search
|
||||
select
|
||||
"memories".*,
|
||||
(
|
||||
select
|
||||
coalesce(json_agg(agg), '[]')
|
||||
|
|
@ -20,7 +45,8 @@ select
|
|||
order by
|
||||
"assets"."fileCreatedAt" asc
|
||||
) as agg
|
||||
) as "assets"
|
||||
) as "assets",
|
||||
"memories".*
|
||||
from
|
||||
"memories"
|
||||
where
|
||||
|
|
@ -31,7 +57,6 @@ order by
|
|||
|
||||
-- MemoryRepository.search (date filter)
|
||||
select
|
||||
"memories".*,
|
||||
(
|
||||
select
|
||||
coalesce(json_agg(agg), '[]')
|
||||
|
|
@ -49,7 +74,8 @@ select
|
|||
order by
|
||||
"assets"."fileCreatedAt" asc
|
||||
) as agg
|
||||
) as "assets"
|
||||
) as "assets",
|
||||
"memories".*
|
||||
from
|
||||
"memories"
|
||||
where
|
||||
|
|
|
|||
|
|
@ -28,14 +28,36 @@ export class MemoryRepository implements IBulkAsset {
|
|||
.execute();
|
||||
}
|
||||
|
||||
searchBuilder(ownerId: string, dto: MemorySearchDto) {
|
||||
return this.db
|
||||
.selectFrom('memories')
|
||||
.$if(dto.isSaved !== undefined, (qb) => qb.where('isSaved', '=', dto.isSaved!))
|
||||
.$if(dto.type !== undefined, (qb) => qb.where('type', '=', dto.type!))
|
||||
.$if(dto.for !== undefined, (qb) =>
|
||||
qb
|
||||
.where((where) => where.or([where('showAt', 'is', null), where('showAt', '<=', dto.for!)]))
|
||||
.where((where) => where.or([where('hideAt', 'is', null), where('hideAt', '>=', dto.for!)])),
|
||||
)
|
||||
.where('deletedAt', dto.isTrashed ? 'is not' : 'is', null)
|
||||
.where('ownerId', '=', ownerId);
|
||||
}
|
||||
|
||||
@GenerateSql(
|
||||
{ params: [DummyValue.UUID, {}] },
|
||||
{ name: 'date filter', params: [DummyValue.UUID, { for: DummyValue.DATE }] },
|
||||
)
|
||||
statistics(ownerId: string, dto: MemorySearchDto) {
|
||||
return this.searchBuilder(ownerId, dto)
|
||||
.select((qb) => qb.fn.countAll<number>().as('total'))
|
||||
.executeTakeFirstOrThrow();
|
||||
}
|
||||
|
||||
@GenerateSql(
|
||||
{ params: [DummyValue.UUID, {}] },
|
||||
{ name: 'date filter', params: [DummyValue.UUID, { for: DummyValue.DATE }] },
|
||||
)
|
||||
search(ownerId: string, dto: MemorySearchDto) {
|
||||
return this.db
|
||||
.selectFrom('memories')
|
||||
.selectAll('memories')
|
||||
return this.searchBuilder(ownerId, dto)
|
||||
.select((eb) =>
|
||||
jsonArrayFrom(
|
||||
eb
|
||||
|
|
@ -48,15 +70,7 @@ export class MemoryRepository implements IBulkAsset {
|
|||
.where('assets.deletedAt', 'is', null),
|
||||
).as('assets'),
|
||||
)
|
||||
.$if(dto.isSaved !== undefined, (qb) => qb.where('isSaved', '=', dto.isSaved!))
|
||||
.$if(dto.type !== undefined, (qb) => qb.where('type', '=', dto.type!))
|
||||
.$if(dto.for !== undefined, (qb) =>
|
||||
qb
|
||||
.where((where) => where.or([where('showAt', 'is', null), where('showAt', '<=', dto.for!)]))
|
||||
.where((where) => where.or([where('hideAt', 'is', null), where('hideAt', '>=', dto.for!)])),
|
||||
)
|
||||
.where('deletedAt', dto.isTrashed ? 'is not' : 'is', null)
|
||||
.where('ownerId', '=', ownerId)
|
||||
.selectAll('memories')
|
||||
.orderBy('memoryAt', 'desc')
|
||||
.execute();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,6 +82,10 @@ export class MemoryService extends BaseService {
|
|||
return memories.map((memory) => mapMemory(memory, auth));
|
||||
}
|
||||
|
||||
statistics(auth: AuthDto, dto: MemorySearchDto) {
|
||||
return this.memoryRepository.statistics(auth.user.id, dto);
|
||||
}
|
||||
|
||||
async get(auth: AuthDto, id: string): Promise<MemoryResponseDto> {
|
||||
await this.requireAccess({ auth, permission: Permission.MEMORY_READ, ids: [id] });
|
||||
const memory = await this.findOrFail(id);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue