mirror of https://github.com/immich-app/immich.git
Merge bb0ee28486 into 4cbce072be
commit
9dd5e84496
@ -0,0 +1,69 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Insertable, Kysely, sql } from 'kysely';
|
||||
import _ from 'lodash';
|
||||
import { DateTime } from 'luxon';
|
||||
import { InjectKysely } from 'nestjs-kysely';
|
||||
import { DummyValue, GenerateSql } from 'src/decorators';
|
||||
import { DB } from 'src/schema';
|
||||
import { DownloadRequestTable } from 'src/schema/tables/download-request.table';
|
||||
|
||||
@Injectable()
|
||||
export class DownloadRequestRepository {
|
||||
constructor(@InjectKysely() private db: Kysely<DB>) {}
|
||||
|
||||
cleanup() {
|
||||
return this.db
|
||||
.deleteFrom('download_request')
|
||||
.where('download_request.expiresAt', '<=', DateTime.now().toJSDate())
|
||||
.returning(['id'])
|
||||
.execute();
|
||||
}
|
||||
|
||||
@GenerateSql({ params: [DummyValue.UUID] })
|
||||
get(id: string) {
|
||||
return this.db
|
||||
.selectFrom('download_request')
|
||||
.selectAll('download_request')
|
||||
.where((eb) =>
|
||||
eb.and([eb('download_request.id', '=', id), eb('download_request.expiresAt', '>', DateTime.now().toJSDate())]),
|
||||
)
|
||||
.leftJoin('download_request_asset', 'download_request_asset.downloadRequestId', 'download_request.id')
|
||||
.select((eb) =>
|
||||
eb.fn
|
||||
.coalesce(eb.fn.jsonAgg('download_request_asset.assetId'), sql`'[]'`)
|
||||
.$castTo<string[]>()
|
||||
.as('assetIds'),
|
||||
)
|
||||
.groupBy('download_request.id')
|
||||
.executeTakeFirstOrThrow();
|
||||
}
|
||||
|
||||
async create(entity: Insertable<DownloadRequestTable> & { assetIds?: string[] }) {
|
||||
const { id } = await this.db
|
||||
.insertInto('download_request')
|
||||
.values(_.omit(entity, 'assetIds'))
|
||||
.returningAll()
|
||||
.executeTakeFirstOrThrow();
|
||||
|
||||
if (entity.assetIds && entity.assetIds.length > 0) {
|
||||
await this.db
|
||||
.insertInto('download_request_asset')
|
||||
.values(entity.assetIds!.map((assetId) => ({ assetId, downloadRequestId: id })))
|
||||
.execute();
|
||||
}
|
||||
|
||||
return this.getDownloadRequest(id);
|
||||
}
|
||||
|
||||
async remove(id: string): Promise<void> {
|
||||
await this.db.deleteFrom('download_request').where('download_request.id', '=', id).execute();
|
||||
}
|
||||
|
||||
private getDownloadRequest(id: string) {
|
||||
return this.db
|
||||
.selectFrom('download_request')
|
||||
.selectAll('download_request')
|
||||
.where('download_request.id', '=', id)
|
||||
.executeTakeFirstOrThrow();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
import { Kysely, sql } from 'kysely';
|
||||
|
||||
export async function up(db: Kysely<any>): Promise<void> {
|
||||
await sql`CREATE TABLE "download_request" (
|
||||
"id" uuid NOT NULL DEFAULT uuid_generate_v4(),
|
||||
"expiresAt" timestamp with time zone NOT NULL,
|
||||
CONSTRAINT "download_request_pkey" PRIMARY KEY ("id")
|
||||
);`.execute(db);
|
||||
await sql`CREATE TABLE "download_request_asset" (
|
||||
"assetId" uuid NOT NULL,
|
||||
"downloadRequestId" uuid NOT NULL,
|
||||
CONSTRAINT "download_request_asset_assetId_fkey" FOREIGN KEY ("assetId") REFERENCES "asset" ("id") ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
CONSTRAINT "download_request_asset_downloadRequestId_fkey" FOREIGN KEY ("downloadRequestId") REFERENCES "download_request" ("id") ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
CONSTRAINT "download_request_asset_pkey" PRIMARY KEY ("assetId", "downloadRequestId")
|
||||
);`.execute(db);
|
||||
await sql`CREATE INDEX "download_request_asset_assetId_idx" ON "download_request_asset" ("assetId");`.execute(db);
|
||||
await sql`CREATE INDEX "download_request_asset_downloadRequestId_idx" ON "download_request_asset" ("downloadRequestId");`.execute(db);
|
||||
}
|
||||
|
||||
export async function down(db: Kysely<any>): Promise<void> {
|
||||
await sql`DROP TABLE "download_request_asset";`.execute(db);
|
||||
await sql`DROP TABLE "download_request";`.execute(db);
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
import { AssetTable } from 'src/schema/tables/asset.table';
|
||||
import { DownloadRequestTable } from 'src/schema/tables/download-request.table';
|
||||
import { ForeignKeyColumn, Table } from 'src/sql-tools';
|
||||
|
||||
@Table('download_request_asset')
|
||||
export class DownloadRequestAssetTable {
|
||||
@ForeignKeyColumn(() => AssetTable, { onUpdate: 'CASCADE', onDelete: 'CASCADE', primary: true })
|
||||
assetId!: string;
|
||||
|
||||
@ForeignKeyColumn(() => DownloadRequestTable, { onUpdate: 'CASCADE', onDelete: 'CASCADE', primary: true })
|
||||
downloadRequestId!: string;
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
import { Column, Generated, PrimaryGeneratedColumn, Table, Timestamp } from 'src/sql-tools';
|
||||
|
||||
@Table('download_request')
|
||||
export class DownloadRequestTable {
|
||||
@PrimaryGeneratedColumn()
|
||||
id!: Generated<string>;
|
||||
|
||||
@Column({ type: 'timestamp with time zone' })
|
||||
expiresAt!: Timestamp;
|
||||
}
|
||||
Loading…
Reference in New Issue