mirror of
https://github.com/immich-app/immich
synced 2025-11-14 17:36:12 +00:00
feat: sync assets, partner assets, exif, and partner exif (#16658)
* feat: sync assets, partner assets, exif, and partner exif Co-authored-by: Zack Pollard <zack@futo.org> Co-authored-by: Alex Tran <alex.tran1502@gmail.com> * refactor: remove duplicate where clause and orderBy statements in sync queries * fix: asset deletes not filtering by ownerId --------- Co-authored-by: Zack Pollard <zack@futo.org> Co-authored-by: Alex Tran <alex.tran1502@gmail.com> Co-authored-by: Zack Pollard <zackpollard@ymail.com>
This commit is contained in:
parent
e97df503f2
commit
a96bba4b26
28 changed files with 2037 additions and 46 deletions
37
server/src/migrations/1741191762113-AssetAuditTable.ts
Normal file
37
server/src/migrations/1741191762113-AssetAuditTable.ts
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||
|
||||
export class AssetAuditTable1741191762113 implements MigrationInterface {
|
||||
name = 'AssetAuditTable1741191762113'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`CREATE TABLE "assets_audit" ("id" uuid NOT NULL DEFAULT immich_uuid_v7(), "assetId" uuid NOT NULL, "ownerId" uuid NOT NULL, "deletedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT clock_timestamp(), CONSTRAINT "PK_99bd5c015f81a641927a32b4212" PRIMARY KEY ("id"))`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_assets_audit_asset_id" ON "assets_audit" ("assetId") `);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_assets_audit_owner_id" ON "assets_audit" ("ownerId") `);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_assets_audit_deleted_at" ON "assets_audit" ("deletedAt") `);
|
||||
await queryRunner.query(`CREATE OR REPLACE FUNCTION assets_delete_audit() RETURNS TRIGGER AS
|
||||
$$
|
||||
BEGIN
|
||||
INSERT INTO assets_audit ("assetId", "ownerId")
|
||||
SELECT "id", "ownerId"
|
||||
FROM OLD;
|
||||
RETURN NULL;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql`
|
||||
);
|
||||
await queryRunner.query(`CREATE OR REPLACE TRIGGER assets_delete_audit
|
||||
AFTER DELETE ON assets
|
||||
REFERENCING OLD TABLE AS OLD
|
||||
FOR EACH STATEMENT
|
||||
EXECUTE FUNCTION assets_delete_audit();
|
||||
`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`DROP TRIGGER assets_delete_audit`);
|
||||
await queryRunner.query(`DROP FUNCTION assets_delete_audit`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_assets_audit_deleted_at"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_assets_audit_owner_id"`);
|
||||
await queryRunner.query(`DROP INDEX "IDX_assets_audit_asset_id"`);
|
||||
await queryRunner.query(`DROP TABLE "assets_audit"`);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
export class FixAssetAndUserCascadeConditions1741280328985 implements MigrationInterface {
|
||||
name = 'FixAssetAndUserCascadeConditions1741280328985';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`
|
||||
CREATE OR REPLACE TRIGGER assets_delete_audit
|
||||
AFTER DELETE ON assets
|
||||
REFERENCING OLD TABLE AS OLD
|
||||
FOR EACH STATEMENT
|
||||
WHEN (pg_trigger_depth() = 0)
|
||||
EXECUTE FUNCTION assets_delete_audit();`);
|
||||
await queryRunner.query(`
|
||||
CREATE OR REPLACE TRIGGER users_delete_audit
|
||||
AFTER DELETE ON users
|
||||
REFERENCING OLD TABLE AS OLD
|
||||
FOR EACH STATEMENT
|
||||
WHEN (pg_trigger_depth() = 0)
|
||||
EXECUTE FUNCTION users_delete_audit();`);
|
||||
await queryRunner.query(`
|
||||
CREATE OR REPLACE TRIGGER partners_delete_audit
|
||||
AFTER DELETE ON partners
|
||||
REFERENCING OLD TABLE AS OLD
|
||||
FOR EACH STATEMENT
|
||||
WHEN (pg_trigger_depth() = 0)
|
||||
EXECUTE FUNCTION partners_delete_audit();`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`
|
||||
CREATE OR REPLACE TRIGGER assets_delete_audit
|
||||
AFTER DELETE ON assets
|
||||
REFERENCING OLD TABLE AS OLD
|
||||
FOR EACH STATEMENT
|
||||
EXECUTE FUNCTION assets_delete_audit();`);
|
||||
await queryRunner.query(`
|
||||
CREATE OR REPLACE TRIGGER users_delete_audit
|
||||
AFTER DELETE ON users
|
||||
REFERENCING OLD TABLE AS OLD
|
||||
FOR EACH STATEMENT
|
||||
EXECUTE FUNCTION users_delete_audit();`);
|
||||
await queryRunner.query(`
|
||||
CREATE OR REPLACE TRIGGER partners_delete_audit
|
||||
AFTER DELETE ON partners
|
||||
REFERENCING OLD TABLE AS OLD
|
||||
FOR EACH STATEMENT
|
||||
EXECUTE FUNCTION partners_delete_audit();`);
|
||||
}
|
||||
}
|
||||
25
server/src/migrations/1741281344519-AddExifUpdateId.ts
Normal file
25
server/src/migrations/1741281344519-AddExifUpdateId.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
export class AddExifUpdateId1741281344519 implements MigrationInterface {
|
||||
name = 'AddExifUpdateId1741281344519';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "exif" ADD "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT clock_timestamp()`,
|
||||
);
|
||||
await queryRunner.query(`ALTER TABLE "exif" ADD "updateId" uuid NOT NULL DEFAULT immich_uuid_v7()`);
|
||||
await queryRunner.query(`CREATE INDEX "IDX_asset_exif_update_id" ON "exif" ("updateId") `);
|
||||
await queryRunner.query(`
|
||||
create trigger asset_exif_updated_at
|
||||
before update on exif
|
||||
for each row execute procedure updated_at()
|
||||
`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`DROP INDEX "public"."IDX_asset_exif_update_id"`);
|
||||
await queryRunner.query(`ALTER TABLE "exif" DROP COLUMN "updateId"`);
|
||||
await queryRunner.query(`ALTER TABLE "exif" DROP COLUMN "updatedAt"`);
|
||||
await queryRunner.query(`DROP TRIGGER asset_exif_updated_at on exif`);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue