mirror of
https://github.com/immich-app/immich.git
synced 2025-04-17 21:46:25 +02:00
feat: updateId uuidv7 column for all entities with updatedAt (#16353)
This commit is contained in:
parent
128d653fc6
commit
967c69317b
18 changed files with 222 additions and 4 deletions
13
server/src/db.d.ts
vendored
13
server/src/db.d.ts
vendored
|
@ -41,6 +41,7 @@ export interface Activity {
|
||||||
id: Generated<string>;
|
id: Generated<string>;
|
||||||
isLiked: Generated<boolean>;
|
isLiked: Generated<boolean>;
|
||||||
updatedAt: Generated<Timestamp>;
|
updatedAt: Generated<Timestamp>;
|
||||||
|
updateId: Generated<string>;
|
||||||
userId: string;
|
userId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +59,7 @@ export interface Albums {
|
||||||
order: Generated<string>;
|
order: Generated<string>;
|
||||||
ownerId: string;
|
ownerId: string;
|
||||||
updatedAt: Generated<Timestamp>;
|
updatedAt: Generated<Timestamp>;
|
||||||
|
updateId: Generated<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AlbumsAssetsAssets {
|
export interface AlbumsAssetsAssets {
|
||||||
|
@ -79,6 +81,7 @@ export interface ApiKeys {
|
||||||
name: string;
|
name: string;
|
||||||
permissions: Permission[];
|
permissions: Permission[];
|
||||||
updatedAt: Generated<Timestamp>;
|
updatedAt: Generated<Timestamp>;
|
||||||
|
updateId: Generated<string>;
|
||||||
userId: string;
|
userId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,6 +106,7 @@ export interface AssetFiles {
|
||||||
path: string;
|
path: string;
|
||||||
type: string;
|
type: string;
|
||||||
updatedAt: Generated<Timestamp>;
|
updatedAt: Generated<Timestamp>;
|
||||||
|
updateId: Generated<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AssetJobStatus {
|
export interface AssetJobStatus {
|
||||||
|
@ -143,6 +147,7 @@ export interface Assets {
|
||||||
thumbhash: Buffer | null;
|
thumbhash: Buffer | null;
|
||||||
type: string;
|
type: string;
|
||||||
updatedAt: Generated<Timestamp>;
|
updatedAt: Generated<Timestamp>;
|
||||||
|
updateId: Generated<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AssetStack {
|
export interface AssetStack {
|
||||||
|
@ -221,6 +226,7 @@ export interface Libraries {
|
||||||
ownerId: string;
|
ownerId: string;
|
||||||
refreshedAt: Timestamp | null;
|
refreshedAt: Timestamp | null;
|
||||||
updatedAt: Generated<Timestamp>;
|
updatedAt: Generated<Timestamp>;
|
||||||
|
updateId: Generated<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Memories {
|
export interface Memories {
|
||||||
|
@ -236,6 +242,7 @@ export interface Memories {
|
||||||
showAt: Timestamp | null;
|
showAt: Timestamp | null;
|
||||||
type: string;
|
type: string;
|
||||||
updatedAt: Generated<Timestamp>;
|
updatedAt: Generated<Timestamp>;
|
||||||
|
updateId: Generated<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MemoriesAssetsAssets {
|
export interface MemoriesAssetsAssets {
|
||||||
|
@ -271,6 +278,7 @@ export interface Partners {
|
||||||
sharedById: string;
|
sharedById: string;
|
||||||
sharedWithId: string;
|
sharedWithId: string;
|
||||||
updatedAt: Generated<Timestamp>;
|
updatedAt: Generated<Timestamp>;
|
||||||
|
updateId: Generated<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Person {
|
export interface Person {
|
||||||
|
@ -285,6 +293,7 @@ export interface Person {
|
||||||
ownerId: string;
|
ownerId: string;
|
||||||
thumbnailPath: Generated<string>;
|
thumbnailPath: Generated<string>;
|
||||||
updatedAt: Generated<Timestamp>;
|
updatedAt: Generated<Timestamp>;
|
||||||
|
updateId: Generated<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Sessions {
|
export interface Sessions {
|
||||||
|
@ -294,6 +303,7 @@ export interface Sessions {
|
||||||
id: Generated<string>;
|
id: Generated<string>;
|
||||||
token: string;
|
token: string;
|
||||||
updatedAt: Generated<Timestamp>;
|
updatedAt: Generated<Timestamp>;
|
||||||
|
updateId: Generated<string>;
|
||||||
userId: string;
|
userId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,6 +313,7 @@ export interface SessionSyncCheckpoints {
|
||||||
sessionId: string;
|
sessionId: string;
|
||||||
type: SyncEntityType;
|
type: SyncEntityType;
|
||||||
updatedAt: Generated<Timestamp>;
|
updatedAt: Generated<Timestamp>;
|
||||||
|
updateId: Generated<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -358,6 +369,7 @@ export interface Tags {
|
||||||
id: Generated<string>;
|
id: Generated<string>;
|
||||||
parentId: string | null;
|
parentId: string | null;
|
||||||
updatedAt: Generated<Timestamp>;
|
updatedAt: Generated<Timestamp>;
|
||||||
|
updateId: Generated<string>;
|
||||||
userId: string;
|
userId: string;
|
||||||
value: string;
|
value: string;
|
||||||
}
|
}
|
||||||
|
@ -399,6 +411,7 @@ export interface Users {
|
||||||
status: Generated<string>;
|
status: Generated<string>;
|
||||||
storageLabel: string | null;
|
storageLabel: string | null;
|
||||||
updatedAt: Generated<Timestamp>;
|
updatedAt: Generated<Timestamp>;
|
||||||
|
updateId: Generated<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UsersAudit {
|
export interface UsersAudit {
|
||||||
|
|
|
@ -25,6 +25,10 @@ export class ActivityEntity {
|
||||||
@UpdateDateColumn({ type: 'timestamptz' })
|
@UpdateDateColumn({ type: 'timestamptz' })
|
||||||
updatedAt!: Date;
|
updatedAt!: Date;
|
||||||
|
|
||||||
|
@Index('IDX_activity_update_id')
|
||||||
|
@Column({ type: 'uuid', nullable: false, default: () => 'immich_uuid_v7()' })
|
||||||
|
updateId?: string;
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
albumId!: string;
|
albumId!: string;
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import {
|
||||||
CreateDateColumn,
|
CreateDateColumn,
|
||||||
DeleteDateColumn,
|
DeleteDateColumn,
|
||||||
Entity,
|
Entity,
|
||||||
|
Index,
|
||||||
JoinTable,
|
JoinTable,
|
||||||
ManyToMany,
|
ManyToMany,
|
||||||
ManyToOne,
|
ManyToOne,
|
||||||
|
@ -39,6 +40,10 @@ export class AlbumEntity {
|
||||||
@UpdateDateColumn({ type: 'timestamptz' })
|
@UpdateDateColumn({ type: 'timestamptz' })
|
||||||
updatedAt!: Date;
|
updatedAt!: Date;
|
||||||
|
|
||||||
|
@Index('IDX_albums_update_id')
|
||||||
|
@Column({ type: 'uuid', nullable: false, default: () => 'immich_uuid_v7()' })
|
||||||
|
updateId?: string;
|
||||||
|
|
||||||
@DeleteDateColumn({ type: 'timestamptz' })
|
@DeleteDateColumn({ type: 'timestamptz' })
|
||||||
deletedAt!: Date | null;
|
deletedAt!: Date | null;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { UserEntity } from 'src/entities/user.entity';
|
import { UserEntity } from 'src/entities/user.entity';
|
||||||
import { Permission } from 'src/enum';
|
import { Permission } from 'src/enum';
|
||||||
import { Column, CreateDateColumn, Entity, ManyToOne, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm';
|
import { Column, CreateDateColumn, Entity, Index, ManyToOne, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm';
|
||||||
|
|
||||||
@Entity('api_keys')
|
@Entity('api_keys')
|
||||||
export class APIKeyEntity {
|
export class APIKeyEntity {
|
||||||
|
@ -27,4 +27,8 @@ export class APIKeyEntity {
|
||||||
|
|
||||||
@UpdateDateColumn({ type: 'timestamptz' })
|
@UpdateDateColumn({ type: 'timestamptz' })
|
||||||
updatedAt!: Date;
|
updatedAt!: Date;
|
||||||
|
|
||||||
|
@Index('IDX_api_keys_update_id')
|
||||||
|
@Column({ type: 'uuid', nullable: false, default: () => 'immich_uuid_v7()' })
|
||||||
|
updateId?: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,10 @@ export class AssetFileEntity {
|
||||||
@UpdateDateColumn({ type: 'timestamptz' })
|
@UpdateDateColumn({ type: 'timestamptz' })
|
||||||
updatedAt!: Date;
|
updatedAt!: Date;
|
||||||
|
|
||||||
|
@Index('IDX_asset_files_update_id')
|
||||||
|
@Column({ type: 'uuid', nullable: false, default: () => 'immich_uuid_v7()' })
|
||||||
|
updateId?: string;
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
type!: AssetFileType;
|
type!: AssetFileType;
|
||||||
|
|
||||||
|
|
|
@ -96,6 +96,10 @@ export class AssetEntity {
|
||||||
@UpdateDateColumn({ type: 'timestamptz' })
|
@UpdateDateColumn({ type: 'timestamptz' })
|
||||||
updatedAt!: Date;
|
updatedAt!: Date;
|
||||||
|
|
||||||
|
@Index('IDX_assets_update_id')
|
||||||
|
@Column({ type: 'uuid', nullable: false, default: () => 'immich_uuid_v7()' })
|
||||||
|
updateId?: string;
|
||||||
|
|
||||||
@DeleteDateColumn({ type: 'timestamptz', nullable: true })
|
@DeleteDateColumn({ type: 'timestamptz', nullable: true })
|
||||||
deletedAt!: Date | null;
|
deletedAt!: Date | null;
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import {
|
||||||
CreateDateColumn,
|
CreateDateColumn,
|
||||||
DeleteDateColumn,
|
DeleteDateColumn,
|
||||||
Entity,
|
Entity,
|
||||||
|
Index,
|
||||||
JoinTable,
|
JoinTable,
|
||||||
ManyToOne,
|
ManyToOne,
|
||||||
OneToMany,
|
OneToMany,
|
||||||
|
@ -42,6 +43,10 @@ export class LibraryEntity {
|
||||||
@UpdateDateColumn({ type: 'timestamptz' })
|
@UpdateDateColumn({ type: 'timestamptz' })
|
||||||
updatedAt!: Date;
|
updatedAt!: Date;
|
||||||
|
|
||||||
|
@Index('IDX_libraries_update_id')
|
||||||
|
@Column({ type: 'uuid', nullable: false, default: () => 'immich_uuid_v7()' })
|
||||||
|
updateId?: string;
|
||||||
|
|
||||||
@DeleteDateColumn({ type: 'timestamptz' })
|
@DeleteDateColumn({ type: 'timestamptz' })
|
||||||
deletedAt?: Date;
|
deletedAt?: Date;
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import {
|
||||||
CreateDateColumn,
|
CreateDateColumn,
|
||||||
DeleteDateColumn,
|
DeleteDateColumn,
|
||||||
Entity,
|
Entity,
|
||||||
|
Index,
|
||||||
JoinTable,
|
JoinTable,
|
||||||
ManyToMany,
|
ManyToMany,
|
||||||
ManyToOne,
|
ManyToOne,
|
||||||
|
@ -30,6 +31,10 @@ export class MemoryEntity<T extends MemoryType = MemoryType> {
|
||||||
@UpdateDateColumn({ type: 'timestamptz' })
|
@UpdateDateColumn({ type: 'timestamptz' })
|
||||||
updatedAt!: Date;
|
updatedAt!: Date;
|
||||||
|
|
||||||
|
@Index('IDX_memories_update_id')
|
||||||
|
@Column({ type: 'uuid', nullable: false, default: () => 'immich_uuid_v7()' })
|
||||||
|
updateId?: string;
|
||||||
|
|
||||||
@DeleteDateColumn({ type: 'timestamptz' })
|
@DeleteDateColumn({ type: 'timestamptz' })
|
||||||
deletedAt?: Date;
|
deletedAt?: Date;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,14 @@
|
||||||
import { UserEntity } from 'src/entities/user.entity';
|
import { UserEntity } from 'src/entities/user.entity';
|
||||||
import { Column, CreateDateColumn, Entity, JoinColumn, ManyToOne, PrimaryColumn, UpdateDateColumn } from 'typeorm';
|
import {
|
||||||
|
Column,
|
||||||
|
CreateDateColumn,
|
||||||
|
Entity,
|
||||||
|
Index,
|
||||||
|
JoinColumn,
|
||||||
|
ManyToOne,
|
||||||
|
PrimaryColumn,
|
||||||
|
UpdateDateColumn,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
@Entity('partners')
|
@Entity('partners')
|
||||||
export class PartnerEntity {
|
export class PartnerEntity {
|
||||||
|
@ -23,6 +32,10 @@ export class PartnerEntity {
|
||||||
@UpdateDateColumn({ type: 'timestamptz' })
|
@UpdateDateColumn({ type: 'timestamptz' })
|
||||||
updatedAt!: Date;
|
updatedAt!: Date;
|
||||||
|
|
||||||
|
@Index('IDX_partners_update_id')
|
||||||
|
@Column({ type: 'uuid', nullable: false, default: () => 'immich_uuid_v7()' })
|
||||||
|
updateId?: string;
|
||||||
|
|
||||||
@Column({ type: 'boolean', default: false })
|
@Column({ type: 'boolean', default: false })
|
||||||
inTimeline!: boolean;
|
inTimeline!: boolean;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import {
|
||||||
Column,
|
Column,
|
||||||
CreateDateColumn,
|
CreateDateColumn,
|
||||||
Entity,
|
Entity,
|
||||||
|
Index,
|
||||||
ManyToOne,
|
ManyToOne,
|
||||||
OneToMany,
|
OneToMany,
|
||||||
PrimaryGeneratedColumn,
|
PrimaryGeneratedColumn,
|
||||||
|
@ -23,6 +24,10 @@ export class PersonEntity {
|
||||||
@UpdateDateColumn({ type: 'timestamptz' })
|
@UpdateDateColumn({ type: 'timestamptz' })
|
||||||
updatedAt!: Date;
|
updatedAt!: Date;
|
||||||
|
|
||||||
|
@Index('IDX_person_update_id')
|
||||||
|
@Column({ type: 'uuid', nullable: false, default: () => 'immich_uuid_v7()' })
|
||||||
|
updateId?: string;
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
ownerId!: string;
|
ownerId!: string;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { ExpressionBuilder } from 'kysely';
|
import { ExpressionBuilder } from 'kysely';
|
||||||
import { DB } from 'src/db';
|
import { DB } from 'src/db';
|
||||||
import { UserEntity } from 'src/entities/user.entity';
|
import { UserEntity } from 'src/entities/user.entity';
|
||||||
import { Column, CreateDateColumn, Entity, ManyToOne, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm';
|
import { Column, CreateDateColumn, Entity, Index, ManyToOne, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm';
|
||||||
|
|
||||||
@Entity('sessions')
|
@Entity('sessions')
|
||||||
export class SessionEntity {
|
export class SessionEntity {
|
||||||
|
@ -23,6 +23,10 @@ export class SessionEntity {
|
||||||
@UpdateDateColumn({ type: 'timestamptz' })
|
@UpdateDateColumn({ type: 'timestamptz' })
|
||||||
updatedAt!: Date;
|
updatedAt!: Date;
|
||||||
|
|
||||||
|
@Index('IDX_sessions_update_id')
|
||||||
|
@Column({ type: 'uuid', nullable: false, default: () => 'immich_uuid_v7()' })
|
||||||
|
updateId!: string;
|
||||||
|
|
||||||
@Column({ default: '' })
|
@Column({ default: '' })
|
||||||
deviceType!: string;
|
deviceType!: string;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { SessionEntity } from 'src/entities/session.entity';
|
import { SessionEntity } from 'src/entities/session.entity';
|
||||||
import { SyncEntityType } from 'src/enum';
|
import { SyncEntityType } from 'src/enum';
|
||||||
import { Column, CreateDateColumn, Entity, ManyToOne, PrimaryColumn, UpdateDateColumn } from 'typeorm';
|
import { Column, CreateDateColumn, Entity, Index, ManyToOne, PrimaryColumn, UpdateDateColumn } from 'typeorm';
|
||||||
|
|
||||||
@Entity('session_sync_checkpoints')
|
@Entity('session_sync_checkpoints')
|
||||||
export class SessionSyncCheckpointEntity {
|
export class SessionSyncCheckpointEntity {
|
||||||
|
@ -19,6 +19,10 @@ export class SessionSyncCheckpointEntity {
|
||||||
@UpdateDateColumn({ type: 'timestamptz' })
|
@UpdateDateColumn({ type: 'timestamptz' })
|
||||||
updatedAt!: Date;
|
updatedAt!: Date;
|
||||||
|
|
||||||
|
@Index('IDX_session_sync_checkpoints_update_id')
|
||||||
|
@Column({ type: 'uuid', nullable: false, default: () => 'immich_uuid_v7()' })
|
||||||
|
updateId?: string;
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
ack!: string;
|
ack!: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import {
|
||||||
Column,
|
Column,
|
||||||
CreateDateColumn,
|
CreateDateColumn,
|
||||||
Entity,
|
Entity,
|
||||||
|
Index,
|
||||||
ManyToMany,
|
ManyToMany,
|
||||||
ManyToOne,
|
ManyToOne,
|
||||||
PrimaryGeneratedColumn,
|
PrimaryGeneratedColumn,
|
||||||
|
@ -30,6 +31,10 @@ export class TagEntity {
|
||||||
@UpdateDateColumn({ type: 'timestamptz' })
|
@UpdateDateColumn({ type: 'timestamptz' })
|
||||||
updatedAt!: Date;
|
updatedAt!: Date;
|
||||||
|
|
||||||
|
@Index('IDX_tags_update_id')
|
||||||
|
@Column({ type: 'uuid', nullable: false, default: () => 'immich_uuid_v7()' })
|
||||||
|
updateId?: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', nullable: true, default: null })
|
@Column({ type: 'varchar', nullable: true, default: null })
|
||||||
color!: string | null;
|
color!: string | null;
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,10 @@ export class UserEntity {
|
||||||
@UpdateDateColumn({ type: 'timestamptz' })
|
@UpdateDateColumn({ type: 'timestamptz' })
|
||||||
updatedAt!: Date;
|
updatedAt!: Date;
|
||||||
|
|
||||||
|
@Index('IDX_users_update_id')
|
||||||
|
@Column({ type: 'uuid', nullable: false, default: () => 'immich_uuid_v7()' })
|
||||||
|
updateId?: string;
|
||||||
|
|
||||||
@OneToMany(() => TagEntity, (tag) => tag.user)
|
@OneToMany(() => TagEntity, (tag) => tag.user)
|
||||||
tags!: TagEntity[];
|
tags!: TagEntity[];
|
||||||
|
|
||||||
|
|
134
server/src/migrations/1740586617223-AddUpdateIdColumns.ts
Normal file
134
server/src/migrations/1740586617223-AddUpdateIdColumns.ts
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||||
|
|
||||||
|
export class AddUpdateIdColumns1740586617223 implements MigrationInterface {
|
||||||
|
name = 'AddUpdateIdColumns1740586617223'
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`
|
||||||
|
create or replace function immich_uuid_v7(p_timestamp timestamp with time zone default clock_timestamp())
|
||||||
|
returns uuid
|
||||||
|
as $$
|
||||||
|
select encode(
|
||||||
|
set_bit(
|
||||||
|
set_bit(
|
||||||
|
overlay(uuid_send(gen_random_uuid())
|
||||||
|
placing substring(int8send(floor(extract(epoch from p_timestamp) * 1000)::bigint) from 3)
|
||||||
|
from 1 for 6
|
||||||
|
),
|
||||||
|
52, 1
|
||||||
|
),
|
||||||
|
53, 1
|
||||||
|
),
|
||||||
|
'hex')::uuid;
|
||||||
|
$$
|
||||||
|
language SQL
|
||||||
|
volatile;
|
||||||
|
`)
|
||||||
|
await queryRunner.query(`
|
||||||
|
CREATE OR REPLACE FUNCTION updated_at() RETURNS TRIGGER
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
as $$
|
||||||
|
BEGIN
|
||||||
|
return new;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
`)
|
||||||
|
await queryRunner.query(`ALTER TABLE "person" ADD "updateId" uuid`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "asset_files" ADD "updateId" uuid`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "libraries" ADD "updateId" uuid`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "tags" ADD "updateId" uuid`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "assets" ADD "updateId" uuid`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "users" ADD "updateId" uuid`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "albums" ADD "updateId" uuid`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "sessions" ADD "updateId" uuid`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "session_sync_checkpoints" ADD "updateId" uuid`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "partners" ADD "updateId" uuid`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "memories" ADD "updateId" uuid`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "api_keys" ADD "updateId" uuid`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "activity" ADD "updateId" uuid`);
|
||||||
|
|
||||||
|
await queryRunner.query(`UPDATE "person" SET "updateId" = immich_uuid_v7("updatedAt")`);
|
||||||
|
await queryRunner.query(`UPDATE "asset_files" SET "updateId" = immich_uuid_v7("updatedAt")`);
|
||||||
|
await queryRunner.query(`UPDATE "libraries" SET "updateId" = immich_uuid_v7("updatedAt")`);
|
||||||
|
await queryRunner.query(`UPDATE "tags" SET "updateId" = immich_uuid_v7("updatedAt")`);
|
||||||
|
await queryRunner.query(`UPDATE "assets" SET "updateId" = immich_uuid_v7("updatedAt")`);
|
||||||
|
await queryRunner.query(`UPDATE "users" SET "updateId" = immich_uuid_v7("updatedAt")`);
|
||||||
|
await queryRunner.query(`UPDATE "albums" SET "updateId" = immich_uuid_v7("updatedAt")`);
|
||||||
|
await queryRunner.query(`UPDATE "sessions" SET "updateId" = immich_uuid_v7("updatedAt")`);
|
||||||
|
await queryRunner.query(`UPDATE "session_sync_checkpoints" SET "updateId" = immich_uuid_v7("updatedAt")`);
|
||||||
|
await queryRunner.query(`UPDATE "partners" SET "updateId" = immich_uuid_v7("updatedAt")`);
|
||||||
|
await queryRunner.query(`UPDATE "memories" SET "updateId" = immich_uuid_v7("updatedAt")`);
|
||||||
|
await queryRunner.query(`UPDATE "api_keys" SET "updateId" = immich_uuid_v7("updatedAt")`);
|
||||||
|
await queryRunner.query(`UPDATE "activity" SET "updateId" = immich_uuid_v7("updatedAt")`);
|
||||||
|
|
||||||
|
await queryRunner.query(`ALTER TABLE "person" ALTER COLUMN "updateId" SET NOT NULL, ALTER COLUMN "updateId" SET DEFAULT immich_uuid_v7()`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "asset_files" ALTER COLUMN "updateId" SET NOT NULL, ALTER COLUMN "updateId" SET DEFAULT immich_uuid_v7()`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "libraries" ALTER COLUMN "updateId" SET NOT NULL, ALTER COLUMN "updateId" SET DEFAULT immich_uuid_v7()`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "tags" ALTER COLUMN "updateId" SET NOT NULL, ALTER COLUMN "updateId" SET DEFAULT immich_uuid_v7()`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "assets" ALTER COLUMN "updateId" SET NOT NULL, ALTER COLUMN "updateId" SET DEFAULT immich_uuid_v7()`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "users" ALTER COLUMN "updateId" SET NOT NULL, ALTER COLUMN "updateId" SET DEFAULT immich_uuid_v7()`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "albums" ALTER COLUMN "updateId" SET NOT NULL, ALTER COLUMN "updateId" SET DEFAULT immich_uuid_v7()`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "sessions" ALTER COLUMN "updateId" SET NOT NULL, ALTER COLUMN "updateId" SET DEFAULT immich_uuid_v7()`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "session_sync_checkpoints" ALTER COLUMN "updateId" SET NOT NULL, ALTER COLUMN "updateId" SET DEFAULT immich_uuid_v7()`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "partners" ALTER COLUMN "updateId" SET NOT NULL, ALTER COLUMN "updateId" SET DEFAULT immich_uuid_v7()`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "memories" ALTER COLUMN "updateId" SET NOT NULL, ALTER COLUMN "updateId" SET DEFAULT immich_uuid_v7()`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "api_keys" ALTER COLUMN "updateId" SET NOT NULL, ALTER COLUMN "updateId" SET DEFAULT immich_uuid_v7()`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "activity" ALTER COLUMN "updateId" SET NOT NULL, ALTER COLUMN "updateId" SET DEFAULT immich_uuid_v7()`);
|
||||||
|
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_person_update_id" ON "person" ("updateId")`);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_asset_files_update_id" ON "asset_files" ("updateId")`);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_libraries_update_id" ON "libraries" ("updateId")`);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_tags_update_id" ON "tags" ("updateId")`);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_assets_update_id" ON "assets" ("updateId")`);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_users_update_id" ON "users" ("updateId")`);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_albums_update_id" ON "albums" ("updateId")`);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_sessions_update_id" ON "sessions" ("updateId")`);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_session_sync_checkpoints_update_id" ON "session_sync_checkpoints" ("updateId")`);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_partners_update_id" ON "partners" ("updateId")`);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_memories_update_id" ON "memories" ("updateId")`);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_api_keys_update_id" ON "api_keys" ("updateId")`);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_activity_update_id" ON "activity" ("updateId")`);
|
||||||
|
|
||||||
|
await queryRunner.query(`
|
||||||
|
CREATE OR REPLACE FUNCTION updated_at() RETURNS TRIGGER
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
as $$
|
||||||
|
DECLARE
|
||||||
|
clock_timestamp TIMESTAMP := clock_timestamp();
|
||||||
|
BEGIN
|
||||||
|
new."updatedAt" = clock_timestamp;
|
||||||
|
new."updateId" = immich_uuid_v7(clock_timestamp);
|
||||||
|
return new;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "activity" DROP COLUMN "updateId"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "api_keys" DROP COLUMN "updateId"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "memories" DROP COLUMN "updateId"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "partners" DROP COLUMN "updateId"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "session_sync_checkpoints" DROP COLUMN "updateId"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "sessions" DROP COLUMN "updateId"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "albums" DROP COLUMN "updateId"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "users" DROP COLUMN "updateId"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "assets" DROP COLUMN "updateId"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "tags" DROP COLUMN "updateId"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "libraries" DROP COLUMN "updateId"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "asset_files" DROP COLUMN "updateId"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "person" DROP COLUMN "updateId"`);
|
||||||
|
await queryRunner.query(`DROP FUNCTION immich_uuid_v7`);
|
||||||
|
await queryRunner.query(`
|
||||||
|
CREATE OR REPLACE FUNCTION updated_at() RETURNS TRIGGER
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
as $$
|
||||||
|
BEGIN
|
||||||
|
new."updatedAt" = now();
|
||||||
|
return new;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -33,6 +33,7 @@ describe('SessionService', () => {
|
||||||
id: '123',
|
id: '123',
|
||||||
token: '420',
|
token: '420',
|
||||||
userId: '42',
|
userId: '42',
|
||||||
|
updateId: 'uuid-v7',
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
2
server/test/fixtures/activity.stub.ts
vendored
2
server/test/fixtures/activity.stub.ts
vendored
|
@ -19,6 +19,7 @@ export const activityStub = {
|
||||||
albumId: albumStub.oneAsset.id,
|
albumId: albumStub.oneAsset.id,
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
|
updateId: 'uuid-v7',
|
||||||
}),
|
}),
|
||||||
liked: Object.freeze<ActivityItem>({
|
liked: Object.freeze<ActivityItem>({
|
||||||
id: 'activity-2',
|
id: 'activity-2',
|
||||||
|
@ -36,5 +37,6 @@ export const activityStub = {
|
||||||
albumId: albumStub.oneAsset.id,
|
albumId: albumStub.oneAsset.id,
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
|
updateId: 'uuid-v7',
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
2
server/test/fixtures/session.stub.ts
vendored
2
server/test/fixtures/session.stub.ts
vendored
|
@ -11,6 +11,7 @@ export const sessionStub = {
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
deviceType: '',
|
deviceType: '',
|
||||||
deviceOS: '',
|
deviceOS: '',
|
||||||
|
updateId: 'uuid-v7',
|
||||||
}),
|
}),
|
||||||
inactive: Object.freeze<SessionEntity>({
|
inactive: Object.freeze<SessionEntity>({
|
||||||
id: 'not_active',
|
id: 'not_active',
|
||||||
|
@ -21,5 +22,6 @@ export const sessionStub = {
|
||||||
updatedAt: new Date('2021-01-01'),
|
updatedAt: new Date('2021-01-01'),
|
||||||
deviceType: 'Mobile',
|
deviceType: 'Mobile',
|
||||||
deviceOS: 'Android',
|
deviceOS: 'Android',
|
||||||
|
updateId: 'uuid-v7',
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue