mirror of
https://github.com/immich-app/immich.git
synced 2025-03-03 15:42:28 +02:00
chore(server): typeorm definitions fix part 3 (#1796)
* chore(server): tidy up exif typeorm entity definition * chore(server): tidy up shared link typeorm entity definition * chore(server): tidy up smart info typeorm entity definition * chore(server): tidy up tag typeorm entity definition * ci: add job that checks typeorm migrations are correct and up-to-date
This commit is contained in:
parent
5d3e8f17d1
commit
d1ea6a897e
45
.github/workflows/test.yml
vendored
45
.github/workflows/test.yml
vendored
@ -79,6 +79,51 @@ jobs:
|
||||
echo "Changed files: ${{ steps.verify-changed-files.outputs.changed_files }}"
|
||||
exit 1
|
||||
|
||||
generated-typeorm-migrations-up-to-date:
|
||||
name: Check generated TypeORM migrations are up-to-date
|
||||
runs-on: ubuntu-latest
|
||||
services:
|
||||
postgres:
|
||||
image: postgres
|
||||
env:
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_DB: immich
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
- 5432:5432
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install server dependencies
|
||||
run: |
|
||||
cd server
|
||||
npm ci
|
||||
- name: Run existing migrations
|
||||
run: |
|
||||
cd server
|
||||
npm run typeorm:migrations:run
|
||||
- name: Generate new migrations
|
||||
continue-on-error: true
|
||||
run: |
|
||||
cd server
|
||||
npm run typeorm:migrations:generate ./libs/infra/src/db/migrations/TestMigration
|
||||
- name: Find file changes
|
||||
uses: tj-actions/verify-changed-files@v13.1
|
||||
id: verify-changed-files
|
||||
with:
|
||||
files: |
|
||||
server/libs/infra/src/db/migrations/
|
||||
- name: Verify files have not changed
|
||||
if: steps.verify-changed-files.outputs.files_changed == 'true'
|
||||
run: |
|
||||
echo "ERROR: Generated files not up to date!"
|
||||
echo "Changed files: ${{ steps.verify-changed-files.outputs.changed_files }}"
|
||||
exit 1
|
||||
|
||||
mobile-integration-tests:
|
||||
name: Run mobile end-to-end integration tests
|
||||
runs-on: macos-latest
|
||||
|
1
mobile/openapi/doc/ExifResponseDto.md
generated
1
mobile/openapi/doc/ExifResponseDto.md
generated
@ -8,7 +8,6 @@ import 'package:openapi/api.dart';
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**id** | **int** | | [optional]
|
||||
**fileSizeInByte** | **int** | | [optional]
|
||||
**make** | **String** | | [optional]
|
||||
**model** | **String** | | [optional]
|
||||
|
1
mobile/openapi/doc/SmartInfoResponseDto.md
generated
1
mobile/openapi/doc/SmartInfoResponseDto.md
generated
@ -8,7 +8,6 @@ import 'package:openapi/api.dart';
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**id** | **String** | | [optional]
|
||||
**tags** | **List<String>** | | [optional] [default to const []]
|
||||
**objects** | **List<String>** | | [optional] [default to const []]
|
||||
|
||||
|
13
mobile/openapi/lib/model/exif_response_dto.dart
generated
13
mobile/openapi/lib/model/exif_response_dto.dart
generated
@ -13,7 +13,6 @@ part of openapi.api;
|
||||
class ExifResponseDto {
|
||||
/// Returns a new [ExifResponseDto] instance.
|
||||
ExifResponseDto({
|
||||
this.id,
|
||||
this.fileSizeInByte,
|
||||
this.make,
|
||||
this.model,
|
||||
@ -35,8 +34,6 @@ class ExifResponseDto {
|
||||
this.country,
|
||||
});
|
||||
|
||||
int? id;
|
||||
|
||||
int? fileSizeInByte;
|
||||
|
||||
String? make;
|
||||
@ -77,7 +74,6 @@ class ExifResponseDto {
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is ExifResponseDto &&
|
||||
other.id == id &&
|
||||
other.fileSizeInByte == fileSizeInByte &&
|
||||
other.make == make &&
|
||||
other.model == model &&
|
||||
@ -101,7 +97,6 @@ class ExifResponseDto {
|
||||
@override
|
||||
int get hashCode =>
|
||||
// ignore: unnecessary_parenthesis
|
||||
(id == null ? 0 : id!.hashCode) +
|
||||
(fileSizeInByte == null ? 0 : fileSizeInByte!.hashCode) +
|
||||
(make == null ? 0 : make!.hashCode) +
|
||||
(model == null ? 0 : model!.hashCode) +
|
||||
@ -123,15 +118,10 @@ class ExifResponseDto {
|
||||
(country == null ? 0 : country!.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'ExifResponseDto[id=$id, fileSizeInByte=$fileSizeInByte, make=$make, model=$model, imageName=$imageName, exifImageWidth=$exifImageWidth, exifImageHeight=$exifImageHeight, orientation=$orientation, dateTimeOriginal=$dateTimeOriginal, modifyDate=$modifyDate, lensModel=$lensModel, fNumber=$fNumber, focalLength=$focalLength, iso=$iso, exposureTime=$exposureTime, latitude=$latitude, longitude=$longitude, city=$city, state=$state, country=$country]';
|
||||
String toString() => 'ExifResponseDto[fileSizeInByte=$fileSizeInByte, make=$make, model=$model, imageName=$imageName, exifImageWidth=$exifImageWidth, exifImageHeight=$exifImageHeight, orientation=$orientation, dateTimeOriginal=$dateTimeOriginal, modifyDate=$modifyDate, lensModel=$lensModel, fNumber=$fNumber, focalLength=$focalLength, iso=$iso, exposureTime=$exposureTime, latitude=$latitude, longitude=$longitude, city=$city, state=$state, country=$country]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
if (this.id != null) {
|
||||
json[r'id'] = this.id;
|
||||
} else {
|
||||
// json[r'id'] = null;
|
||||
}
|
||||
if (this.fileSizeInByte != null) {
|
||||
json[r'fileSizeInByte'] = this.fileSizeInByte;
|
||||
} else {
|
||||
@ -249,7 +239,6 @@ class ExifResponseDto {
|
||||
}());
|
||||
|
||||
return ExifResponseDto(
|
||||
id: mapValueOfType<int>(json, r'id'),
|
||||
fileSizeInByte: mapValueOfType<int>(json, r'fileSizeInByte'),
|
||||
make: mapValueOfType<String>(json, r'make'),
|
||||
model: mapValueOfType<String>(json, r'model'),
|
||||
|
@ -13,46 +13,30 @@ part of openapi.api;
|
||||
class SmartInfoResponseDto {
|
||||
/// Returns a new [SmartInfoResponseDto] instance.
|
||||
SmartInfoResponseDto({
|
||||
this.id,
|
||||
this.tags = const [],
|
||||
this.objects = const [],
|
||||
});
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? id;
|
||||
|
||||
List<String>? tags;
|
||||
|
||||
List<String>? objects;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is SmartInfoResponseDto &&
|
||||
other.id == id &&
|
||||
other.tags == tags &&
|
||||
other.objects == objects;
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
// ignore: unnecessary_parenthesis
|
||||
(id == null ? 0 : id!.hashCode) +
|
||||
(tags == null ? 0 : tags!.hashCode) +
|
||||
(objects == null ? 0 : objects!.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'SmartInfoResponseDto[id=$id, tags=$tags, objects=$objects]';
|
||||
String toString() => 'SmartInfoResponseDto[tags=$tags, objects=$objects]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
if (this.id != null) {
|
||||
json[r'id'] = this.id;
|
||||
} else {
|
||||
// json[r'id'] = null;
|
||||
}
|
||||
if (this.tags != null) {
|
||||
json[r'tags'] = this.tags;
|
||||
} else {
|
||||
@ -85,7 +69,6 @@ class SmartInfoResponseDto {
|
||||
}());
|
||||
|
||||
return SmartInfoResponseDto(
|
||||
id: mapValueOfType<String>(json, r'id'),
|
||||
tags: json[r'tags'] is List
|
||||
? (json[r'tags'] as List).cast<String>()
|
||||
: const [],
|
||||
|
5
mobile/openapi/test/exif_response_dto_test.dart
generated
5
mobile/openapi/test/exif_response_dto_test.dart
generated
@ -16,11 +16,6 @@ void main() {
|
||||
// final instance = ExifResponseDto();
|
||||
|
||||
group('test ExifResponseDto', () {
|
||||
// int id
|
||||
test('to test the property `id`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// int fileSizeInByte
|
||||
test('to test the property `fileSizeInByte`', () async {
|
||||
// TODO
|
||||
|
@ -16,11 +16,6 @@ void main() {
|
||||
// final instance = SmartInfoResponseDto();
|
||||
|
||||
group('test SmartInfoResponseDto', () {
|
||||
// String id
|
||||
test('to test the property `id`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// List<String> tags (default value: const [])
|
||||
test('to test the property `tags`', () async {
|
||||
// TODO
|
||||
|
@ -253,7 +253,7 @@ export class MetadataExtractionProcessor {
|
||||
if (this.isGeocodeInitialized) {
|
||||
const { latitude, longitude } = job.data;
|
||||
const { country, state, city } = await this.reverseGeocodeExif(latitude, longitude);
|
||||
await this.exifRepository.update({ id: job.data.exifId }, { city, state, country });
|
||||
await this.exifRepository.update({ assetId: job.data.assetId }, { city, state, country });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3136,12 +3136,6 @@
|
||||
"ExifResponseDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"nullable": true,
|
||||
"default": null,
|
||||
"format": "int64"
|
||||
},
|
||||
"fileSizeInByte": {
|
||||
"type": "integer",
|
||||
"nullable": true,
|
||||
@ -3245,9 +3239,6 @@
|
||||
"SmartInfoResponseDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"tags": {
|
||||
"nullable": true,
|
||||
"type": "array",
|
||||
|
@ -2,8 +2,6 @@ import { ExifEntity } from '@app/infra/db/entities';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class ExifResponseDto {
|
||||
@ApiProperty({ type: 'integer', format: 'int64' })
|
||||
id?: number | null = null;
|
||||
make?: string | null = null;
|
||||
model?: string | null = null;
|
||||
imageName?: string | null = null;
|
||||
@ -29,7 +27,6 @@ export class ExifResponseDto {
|
||||
|
||||
export function mapExif(entity: ExifEntity): ExifResponseDto {
|
||||
return {
|
||||
id: entity.id,
|
||||
make: entity.make,
|
||||
model: entity.model,
|
||||
imageName: entity.imageName,
|
||||
|
@ -1,14 +1,12 @@
|
||||
import { SmartInfoEntity } from '@app/infra/db/entities';
|
||||
|
||||
export class SmartInfoResponseDto {
|
||||
id?: string;
|
||||
tags?: string[] | null;
|
||||
objects?: string[] | null;
|
||||
}
|
||||
|
||||
export function mapSmartInfo(entity: SmartInfoEntity): SmartInfoResponseDto {
|
||||
return {
|
||||
id: entity.id,
|
||||
tags: entity.tags,
|
||||
objects: entity.objects,
|
||||
};
|
||||
|
@ -25,7 +25,7 @@ export interface IVideoLengthExtractionProcessor {
|
||||
}
|
||||
|
||||
export interface IReverseGeocodingProcessor {
|
||||
exifId: number;
|
||||
assetId: string;
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
}
|
||||
|
@ -119,7 +119,6 @@ export const assetEntityStub = {
|
||||
};
|
||||
|
||||
const assetInfo: ExifResponseDto = {
|
||||
id: 1,
|
||||
make: 'camera-make',
|
||||
model: 'camera-model',
|
||||
imageName: 'fancy-image',
|
||||
@ -155,7 +154,6 @@ const assetResponse: AssetResponseDto = {
|
||||
isFavorite: false,
|
||||
mimeType: 'image/jpeg',
|
||||
smartInfo: {
|
||||
id: 'should-be-a-number',
|
||||
tags: [],
|
||||
objects: ['a', 'b', 'c'],
|
||||
},
|
||||
@ -391,7 +389,6 @@ export const sharedLinkStub = {
|
||||
isFavorite: false,
|
||||
mimeType: 'image/jpeg',
|
||||
smartInfo: {
|
||||
id: 'should-be-a-number',
|
||||
assetId: 'id_1',
|
||||
tags: [],
|
||||
objects: ['a', 'b', 'c'],
|
||||
@ -405,7 +402,6 @@ export const sharedLinkStub = {
|
||||
livePhotoVideoId: null,
|
||||
exifInfo: {
|
||||
livePhotoCID: null,
|
||||
id: 1,
|
||||
assetId: 'id_1',
|
||||
description: 'description',
|
||||
exifImageWidth: 500,
|
||||
|
@ -1,20 +1,19 @@
|
||||
import { Index, JoinColumn, OneToOne } from 'typeorm';
|
||||
import { Index, JoinColumn, OneToOne, PrimaryColumn } from 'typeorm';
|
||||
import { Column } from 'typeorm/decorator/columns/Column';
|
||||
import { PrimaryGeneratedColumn } from 'typeorm/decorator/columns/PrimaryGeneratedColumn';
|
||||
import { Entity } from 'typeorm/decorator/entity/Entity';
|
||||
import { AssetEntity } from './asset.entity';
|
||||
|
||||
@Entity('exif')
|
||||
export class ExifEntity {
|
||||
@PrimaryGeneratedColumn()
|
||||
id!: number;
|
||||
@OneToOne(() => AssetEntity, { onDelete: 'CASCADE', nullable: true })
|
||||
@JoinColumn()
|
||||
asset?: AssetEntity;
|
||||
|
||||
@Index({ unique: true })
|
||||
@Column({ type: 'uuid' })
|
||||
@PrimaryColumn()
|
||||
assetId!: string;
|
||||
|
||||
/* General info */
|
||||
@Column({ type: 'text', nullable: true, default: '' })
|
||||
@Column({ type: 'text', default: '' })
|
||||
description!: string; // or caption
|
||||
|
||||
@Column({ type: 'integer', nullable: true })
|
||||
@ -83,10 +82,6 @@ export class ExifEntity {
|
||||
@Column({ type: 'float8', nullable: true })
|
||||
fps?: number | null;
|
||||
|
||||
@OneToOne(() => AssetEntity, { onDelete: 'CASCADE', nullable: true })
|
||||
@JoinColumn({ name: 'assetId', referencedColumnName: 'id' })
|
||||
asset?: AssetEntity;
|
||||
|
||||
@Index('exif_text_searchable', { synchronize: false })
|
||||
@Column({
|
||||
type: 'tsvector',
|
||||
|
@ -1,4 +1,13 @@
|
||||
import { Column, Entity, Index, ManyToMany, ManyToOne, PrimaryGeneratedColumn, Unique } from 'typeorm';
|
||||
import {
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
Entity,
|
||||
Index,
|
||||
ManyToMany,
|
||||
ManyToOne,
|
||||
PrimaryGeneratedColumn,
|
||||
Unique,
|
||||
} from 'typeorm';
|
||||
import { AlbumEntity } from './album.entity';
|
||||
import { AssetEntity } from './asset.entity';
|
||||
import { UserEntity } from './user.entity';
|
||||
@ -25,7 +34,7 @@ export class SharedLinkEntity {
|
||||
@Column()
|
||||
type!: SharedLinkType;
|
||||
|
||||
@Column({ type: 'timestamptz' })
|
||||
@CreateDateColumn({ type: 'timestamptz' })
|
||||
createdAt!: string;
|
||||
|
||||
@Column({ type: 'timestamptz', nullable: true })
|
||||
@ -56,5 +65,3 @@ export enum SharedLinkType {
|
||||
*/
|
||||
INDIVIDUAL = 'INDIVIDUAL',
|
||||
}
|
||||
|
||||
// npm run typeorm -- migration:generate ./libs/infra/src/db/AddMorePermissionToSharedLink -d ./libs/infra/src/db/config/database.config.ts
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { Column, Entity, Index, JoinColumn, OneToOne, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { Column, Entity, JoinColumn, OneToOne, PrimaryColumn } from 'typeorm';
|
||||
import { AssetEntity } from './asset.entity';
|
||||
|
||||
@Entity('smart_info')
|
||||
export class SmartInfoEntity {
|
||||
@PrimaryGeneratedColumn()
|
||||
id!: string;
|
||||
@OneToOne(() => AssetEntity, { onDelete: 'CASCADE', nullable: true })
|
||||
@JoinColumn({ name: 'assetId', referencedColumnName: 'id' })
|
||||
asset?: AssetEntity;
|
||||
|
||||
@Index({ unique: true })
|
||||
@Column({ type: 'uuid' })
|
||||
@PrimaryColumn()
|
||||
assetId!: string;
|
||||
|
||||
@Column({ type: 'text', array: true, nullable: true })
|
||||
@ -15,8 +15,4 @@ export class SmartInfoEntity {
|
||||
|
||||
@Column({ type: 'text', array: true, nullable: true })
|
||||
objects!: string[] | null;
|
||||
|
||||
@OneToOne(() => AssetEntity, { onDelete: 'CASCADE', nullable: true })
|
||||
@JoinColumn({ name: 'assetId', referencedColumnName: 'id' })
|
||||
asset?: AssetEntity;
|
||||
}
|
||||
|
@ -14,6 +14,9 @@ export class TagEntity {
|
||||
@Column()
|
||||
name!: string;
|
||||
|
||||
@ManyToOne(() => UserEntity, (user) => user.tags)
|
||||
user!: UserEntity;
|
||||
|
||||
@Column()
|
||||
userId!: string;
|
||||
|
||||
@ -22,9 +25,6 @@ export class TagEntity {
|
||||
|
||||
@ManyToMany(() => AssetEntity, (asset) => asset.tags)
|
||||
assets!: AssetEntity[];
|
||||
|
||||
@ManyToOne(() => UserEntity, (user) => user.tags)
|
||||
user!: UserEntity;
|
||||
}
|
||||
|
||||
export enum TagType {
|
||||
|
@ -0,0 +1,28 @@
|
||||
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||
|
||||
export class ExifEntityDefinitionFixes1676848629119 implements MigrationInterface {
|
||||
name = 'ExifEntityDefinitionFixes1676848629119'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "exif" ALTER COLUMN "description" SET NOT NULL`);
|
||||
|
||||
await queryRunner.query(`DROP INDEX "public"."IDX_c0117fdbc50b917ef9067740c4"`);
|
||||
await queryRunner.query(`ALTER TABLE "exif" DROP CONSTRAINT "PK_28663352d85078ad0046dafafaa"`);
|
||||
await queryRunner.query(`ALTER TABLE "exif" DROP COLUMN "id"`);
|
||||
await queryRunner.query(`ALTER TABLE "exif" DROP CONSTRAINT "FK_c0117fdbc50b917ef9067740c44"`);
|
||||
await queryRunner.query(`ALTER TABLE "exif" ADD CONSTRAINT "PK_c0117fdbc50b917ef9067740c44" PRIMARY KEY ("assetId")`);
|
||||
await queryRunner.query(`ALTER TABLE "exif" ADD CONSTRAINT "FK_c0117fdbc50b917ef9067740c44" FOREIGN KEY ("assetId") REFERENCES "assets"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "exif" ALTER COLUMN "description" DROP NOT NULL`);
|
||||
|
||||
await queryRunner.query(`ALTER TABLE "exif" DROP CONSTRAINT "FK_c0117fdbc50b917ef9067740c44"`);
|
||||
await queryRunner.query(`ALTER TABLE "exif" DROP CONSTRAINT "PK_c0117fdbc50b917ef9067740c44"`);
|
||||
await queryRunner.query(`ALTER TABLE "exif" ADD CONSTRAINT "FK_c0117fdbc50b917ef9067740c44" FOREIGN KEY ("assetId") REFERENCES "assets"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
||||
await queryRunner.query(`ALTER TABLE "exif" ADD "id" SERIAL NOT NULL`);
|
||||
await queryRunner.query(`ALTER TABLE "exif" ADD CONSTRAINT "PK_28663352d85078ad0046dafafaa" PRIMARY KEY ("id")`);
|
||||
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_c0117fdbc50b917ef9067740c4" ON "exif" ("assetId") `);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||
|
||||
export class SharedLinkEntityDefinitionFixes1676848694786 implements MigrationInterface {
|
||||
name = 'SharedLinkEntityDefinitionFixes1676848694786'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "shared_links" ALTER COLUMN "createdAt" SET DEFAULT now()`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "shared_links" ALTER COLUMN "createdAt" DROP DEFAULT`);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||
|
||||
export class SmartInfoEntityDefinitionFixes1676852143506 implements MigrationInterface {
|
||||
name = 'SmartInfoEntityDefinitionFixes1676852143506'
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`DROP INDEX "public"."IDX_5e3753aadd956110bf3ec0244a"`);
|
||||
await queryRunner.query(`ALTER TABLE "smart_info" DROP CONSTRAINT "PK_0beace66440e9713f5c40470e46"`);
|
||||
await queryRunner.query(`ALTER TABLE "smart_info" DROP COLUMN "id"`);
|
||||
await queryRunner.query(`ALTER TABLE "smart_info" DROP CONSTRAINT "FK_5e3753aadd956110bf3ec0244ac"`);
|
||||
await queryRunner.query(`ALTER TABLE "smart_info" ADD CONSTRAINT "PK_5e3753aadd956110bf3ec0244ac" PRIMARY KEY ("assetId")`);
|
||||
await queryRunner.query(`ALTER TABLE "smart_info" ADD CONSTRAINT "FK_5e3753aadd956110bf3ec0244ac" FOREIGN KEY ("assetId") REFERENCES "assets"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "smart_info" DROP CONSTRAINT "FK_5e3753aadd956110bf3ec0244ac"`);
|
||||
await queryRunner.query(`ALTER TABLE "smart_info" DROP CONSTRAINT "PK_5e3753aadd956110bf3ec0244ac"`);
|
||||
await queryRunner.query(`ALTER TABLE "smart_info" ADD CONSTRAINT "FK_5e3753aadd956110bf3ec0244ac" FOREIGN KEY ("assetId") REFERENCES "assets"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
|
||||
await queryRunner.query(`ALTER TABLE "smart_info" ADD "id" SERIAL NOT NULL`);
|
||||
await queryRunner.query(`ALTER TABLE "smart_info" ADD CONSTRAINT "PK_0beace66440e9713f5c40470e46" PRIMARY KEY ("id")`);
|
||||
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_5e3753aadd956110bf3ec0244a" ON "smart_info" ("assetId") `);
|
||||
}
|
||||
|
||||
}
|
12
web/src/api/open-api/api.ts
generated
12
web/src/api/open-api/api.ts
generated
@ -1054,12 +1054,6 @@ export interface EditSharedLinkDto {
|
||||
* @interface ExifResponseDto
|
||||
*/
|
||||
export interface ExifResponseDto {
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
* @memberof ExifResponseDto
|
||||
*/
|
||||
'id'?: number | null;
|
||||
/**
|
||||
*
|
||||
* @type {number}
|
||||
@ -1730,12 +1724,6 @@ export interface SignUpDto {
|
||||
* @interface SmartInfoResponseDto
|
||||
*/
|
||||
export interface SmartInfoResponseDto {
|
||||
/**
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof SmartInfoResponseDto
|
||||
*/
|
||||
'id'?: string;
|
||||
/**
|
||||
*
|
||||
* @type {Array<string>}
|
||||
|
Loading…
x
Reference in New Issue
Block a user