mirror of
https://github.com/immich-app/immich.git
synced 2025-07-09 03:04:16 -04:00
refactor: database types (#19624)
This commit is contained in:
parent
09cbc5d3f4
commit
e60bc3c304
@ -29,7 +29,6 @@
|
|||||||
"migrations:run": "node ./dist/bin/migrations.js run",
|
"migrations:run": "node ./dist/bin/migrations.js run",
|
||||||
"schema:drop": "node ./dist/bin/migrations.js query 'DROP schema public cascade; CREATE schema public;'",
|
"schema:drop": "node ./dist/bin/migrations.js query 'DROP schema public cascade; CREATE schema public;'",
|
||||||
"schema:reset": "npm run schema:drop && npm run migrations:run",
|
"schema:reset": "npm run schema:drop && npm run migrations:run",
|
||||||
"kysely:codegen": "npx kysely-codegen --include-pattern=\"(public|vectors).*\" --dialect postgres --url postgres://postgres:postgres@localhost/immich --log-level debug --out-file=./src/db.d.ts",
|
|
||||||
"sync:open-api": "node ./dist/bin/sync-open-api.js",
|
"sync:open-api": "node ./dist/bin/sync-open-api.js",
|
||||||
"sync:sql": "node ./dist/bin/sync-sql.js",
|
"sync:sql": "node ./dist/bin/sync-sql.js",
|
||||||
"email:dev": "email dev -p 3050 --dir src/emails",
|
"email:dev": "email dev -p 3050 --dir src/emails",
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { Selectable } from 'kysely';
|
import { Selectable } from 'kysely';
|
||||||
import { Albums, Exif as DatabaseExif } from 'src/db';
|
|
||||||
import { MapAsset } from 'src/dtos/asset-response.dto';
|
import { MapAsset } from 'src/dtos/asset-response.dto';
|
||||||
import {
|
import {
|
||||||
AlbumUserRole,
|
AlbumUserRole,
|
||||||
@ -13,6 +12,8 @@ import {
|
|||||||
UserAvatarColor,
|
UserAvatarColor,
|
||||||
UserStatus,
|
UserStatus,
|
||||||
} from 'src/enum';
|
} from 'src/enum';
|
||||||
|
import { AlbumTable } from 'src/schema/tables/album.table';
|
||||||
|
import { ExifTable } from 'src/schema/tables/exif.table';
|
||||||
import { UserMetadataItem } from 'src/types';
|
import { UserMetadataItem } from 'src/types';
|
||||||
|
|
||||||
export type AuthUser = {
|
export type AuthUser = {
|
||||||
@ -193,7 +194,7 @@ export type SharedLink = {
|
|||||||
userId: string;
|
userId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Album = Selectable<Albums> & {
|
export type Album = Selectable<AlbumTable> & {
|
||||||
owner: User;
|
owner: User;
|
||||||
assets: MapAsset[];
|
assets: MapAsset[];
|
||||||
};
|
};
|
||||||
@ -239,7 +240,7 @@ export type Session = {
|
|||||||
pinExpiresAt: Date | null;
|
pinExpiresAt: Date | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Exif = Omit<Selectable<DatabaseExif>, 'updatedAt' | 'updateId'>;
|
export type Exif = Omit<Selectable<ExifTable>, 'updatedAt' | 'updateId'>;
|
||||||
|
|
||||||
export type Person = {
|
export type Person = {
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
|
540
server/src/db.d.ts
vendored
540
server/src/db.d.ts
vendored
@ -1,540 +0,0 @@
|
|||||||
/**
|
|
||||||
* This file was generated by kysely-codegen.
|
|
||||||
* Please do not edit it manually.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import type { ColumnType } from 'kysely';
|
|
||||||
import {
|
|
||||||
AlbumUserRole,
|
|
||||||
AssetFileType,
|
|
||||||
AssetOrder,
|
|
||||||
AssetStatus,
|
|
||||||
AssetType,
|
|
||||||
AssetVisibility,
|
|
||||||
MemoryType,
|
|
||||||
NotificationLevel,
|
|
||||||
NotificationType,
|
|
||||||
Permission,
|
|
||||||
SharedLinkType,
|
|
||||||
SourceType,
|
|
||||||
SyncEntityType,
|
|
||||||
} from 'src/enum';
|
|
||||||
import { MemoryAssetAuditTable } from 'src/schema/tables/memory-asset-audit.table';
|
|
||||||
import { MemoryAssetTable } from 'src/schema/tables/memory-asset.table';
|
|
||||||
import { MemoryAuditTable } from 'src/schema/tables/memory-audit.table';
|
|
||||||
import { UserTable } from 'src/schema/tables/user.table';
|
|
||||||
import { UserMetadataItem } from 'src/types';
|
|
||||||
|
|
||||||
export type ArrayType<T> = ArrayTypeImpl<T> extends (infer U)[] ? U[] : ArrayTypeImpl<T>;
|
|
||||||
|
|
||||||
export type ArrayTypeImpl<T> = T extends ColumnType<infer S, infer I, infer U> ? ColumnType<S[], I[], U[]> : T[];
|
|
||||||
|
|
||||||
export type Generated<T> =
|
|
||||||
T extends ColumnType<infer S, infer I, infer U> ? ColumnType<S, I | undefined, U> : ColumnType<T, T | undefined, T>;
|
|
||||||
|
|
||||||
export type Int8 = ColumnType<number>;
|
|
||||||
|
|
||||||
export type Json = JsonValue;
|
|
||||||
|
|
||||||
export type JsonArray = JsonValue[];
|
|
||||||
|
|
||||||
export type JsonObject = {
|
|
||||||
[x: string]: JsonValue | undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type JsonPrimitive = boolean | number | string | null;
|
|
||||||
|
|
||||||
export type JsonValue = JsonArray | JsonObject | JsonPrimitive;
|
|
||||||
|
|
||||||
export type Timestamp = ColumnType<Date, Date | string, Date | string>;
|
|
||||||
|
|
||||||
export interface Activity {
|
|
||||||
albumId: string;
|
|
||||||
assetId: string | null;
|
|
||||||
comment: string | null;
|
|
||||||
createdAt: Generated<Timestamp>;
|
|
||||||
id: Generated<string>;
|
|
||||||
isLiked: Generated<boolean>;
|
|
||||||
updatedAt: Generated<Timestamp>;
|
|
||||||
updateId: Generated<string>;
|
|
||||||
userId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Albums {
|
|
||||||
albumName: Generated<string>;
|
|
||||||
/**
|
|
||||||
* Asset ID to be used as thumbnail
|
|
||||||
*/
|
|
||||||
albumThumbnailAssetId: string | null;
|
|
||||||
createdAt: Generated<Timestamp>;
|
|
||||||
deletedAt: Timestamp | null;
|
|
||||||
description: Generated<string>;
|
|
||||||
id: Generated<string>;
|
|
||||||
isActivityEnabled: Generated<boolean>;
|
|
||||||
order: Generated<AssetOrder>;
|
|
||||||
ownerId: string;
|
|
||||||
updatedAt: Generated<Timestamp>;
|
|
||||||
updateId: Generated<string>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AlbumsAudit {
|
|
||||||
deletedAt: Generated<Timestamp>;
|
|
||||||
id: Generated<string>;
|
|
||||||
albumId: string;
|
|
||||||
userId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AlbumUsersAudit {
|
|
||||||
deletedAt: Generated<Timestamp>;
|
|
||||||
id: Generated<string>;
|
|
||||||
albumId: string;
|
|
||||||
userId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AlbumsAssetsAssets {
|
|
||||||
albumsId: string;
|
|
||||||
assetsId: string;
|
|
||||||
createdAt: Generated<Timestamp>;
|
|
||||||
updatedAt: Generated<Timestamp>;
|
|
||||||
updateId: Generated<string>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AlbumAssetsAudit {
|
|
||||||
deletedAt: Generated<Timestamp>;
|
|
||||||
id: Generated<string>;
|
|
||||||
albumId: string;
|
|
||||||
assetId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AlbumsSharedUsersUsers {
|
|
||||||
albumsId: string;
|
|
||||||
role: Generated<AlbumUserRole>;
|
|
||||||
usersId: string;
|
|
||||||
createId: Generated<string>;
|
|
||||||
createdAt: Generated<Timestamp>;
|
|
||||||
updateId: Generated<string>;
|
|
||||||
updatedAt: Generated<Timestamp>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ApiKeys {
|
|
||||||
createdAt: Generated<Timestamp>;
|
|
||||||
id: Generated<string>;
|
|
||||||
key: string;
|
|
||||||
name: string;
|
|
||||||
permissions: Permission[];
|
|
||||||
updatedAt: Generated<Timestamp>;
|
|
||||||
updateId: Generated<string>;
|
|
||||||
userId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AssetFaces {
|
|
||||||
assetId: string;
|
|
||||||
boundingBoxX1: Generated<number>;
|
|
||||||
boundingBoxX2: Generated<number>;
|
|
||||||
boundingBoxY1: Generated<number>;
|
|
||||||
boundingBoxY2: Generated<number>;
|
|
||||||
deletedAt: Timestamp | null;
|
|
||||||
id: Generated<string>;
|
|
||||||
imageHeight: Generated<number>;
|
|
||||||
imageWidth: Generated<number>;
|
|
||||||
personId: string | null;
|
|
||||||
sourceType: Generated<SourceType>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AssetFiles {
|
|
||||||
assetId: string;
|
|
||||||
createdAt: Generated<Timestamp>;
|
|
||||||
id: Generated<string>;
|
|
||||||
path: string;
|
|
||||||
type: AssetFileType;
|
|
||||||
updatedAt: Generated<Timestamp>;
|
|
||||||
updateId: Generated<string>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AssetJobStatus {
|
|
||||||
assetId: string;
|
|
||||||
duplicatesDetectedAt: Timestamp | null;
|
|
||||||
facesRecognizedAt: Timestamp | null;
|
|
||||||
metadataExtractedAt: Timestamp | null;
|
|
||||||
previewAt: Timestamp | null;
|
|
||||||
thumbnailAt: Timestamp | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AssetsAudit {
|
|
||||||
deletedAt: Generated<Timestamp>;
|
|
||||||
id: Generated<string>;
|
|
||||||
assetId: string;
|
|
||||||
ownerId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Assets {
|
|
||||||
checksum: Buffer;
|
|
||||||
createdAt: Generated<Timestamp>;
|
|
||||||
deletedAt: Timestamp | null;
|
|
||||||
deviceAssetId: string;
|
|
||||||
deviceId: string;
|
|
||||||
duplicateId: string | null;
|
|
||||||
duration: string | null;
|
|
||||||
encodedVideoPath: Generated<string | null>;
|
|
||||||
fileCreatedAt: Timestamp;
|
|
||||||
fileModifiedAt: Timestamp;
|
|
||||||
id: Generated<string>;
|
|
||||||
isExternal: Generated<boolean>;
|
|
||||||
isFavorite: Generated<boolean>;
|
|
||||||
isOffline: Generated<boolean>;
|
|
||||||
visibility: Generated<AssetVisibility>;
|
|
||||||
libraryId: string | null;
|
|
||||||
livePhotoVideoId: string | null;
|
|
||||||
localDateTime: Timestamp;
|
|
||||||
originalFileName: string;
|
|
||||||
originalPath: string;
|
|
||||||
ownerId: string;
|
|
||||||
sidecarPath: string | null;
|
|
||||||
stackId: string | null;
|
|
||||||
status: Generated<AssetStatus>;
|
|
||||||
thumbhash: Buffer | null;
|
|
||||||
type: AssetType;
|
|
||||||
updatedAt: Generated<Timestamp>;
|
|
||||||
updateId: Generated<string>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AssetStack {
|
|
||||||
id: Generated<string>;
|
|
||||||
ownerId: string;
|
|
||||||
primaryAssetId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Audit {
|
|
||||||
action: string;
|
|
||||||
createdAt: Generated<Timestamp>;
|
|
||||||
entityId: string;
|
|
||||||
entityType: string;
|
|
||||||
id: Generated<number>;
|
|
||||||
ownerId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Exif {
|
|
||||||
assetId: string;
|
|
||||||
updateId: Generated<string>;
|
|
||||||
updatedAt: Generated<Timestamp>;
|
|
||||||
autoStackId: string | null;
|
|
||||||
bitsPerSample: number | null;
|
|
||||||
city: string | null;
|
|
||||||
colorspace: string | null;
|
|
||||||
country: string | null;
|
|
||||||
dateTimeOriginal: Timestamp | null;
|
|
||||||
description: Generated<string>;
|
|
||||||
exifImageHeight: number | null;
|
|
||||||
exifImageWidth: number | null;
|
|
||||||
exposureTime: string | null;
|
|
||||||
fileSizeInByte: Int8 | null;
|
|
||||||
fNumber: number | null;
|
|
||||||
focalLength: number | null;
|
|
||||||
fps: number | null;
|
|
||||||
iso: number | null;
|
|
||||||
latitude: number | null;
|
|
||||||
lensModel: string | null;
|
|
||||||
livePhotoCID: string | null;
|
|
||||||
longitude: number | null;
|
|
||||||
make: string | null;
|
|
||||||
model: string | null;
|
|
||||||
modifyDate: Timestamp | null;
|
|
||||||
orientation: string | null;
|
|
||||||
profileDescription: string | null;
|
|
||||||
projectionType: string | null;
|
|
||||||
rating: number | null;
|
|
||||||
state: string | null;
|
|
||||||
timeZone: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface FaceSearch {
|
|
||||||
embedding: string;
|
|
||||||
faceId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GeodataPlaces {
|
|
||||||
admin1Code: string | null;
|
|
||||||
admin1Name: string | null;
|
|
||||||
admin2Code: string | null;
|
|
||||||
admin2Name: string | null;
|
|
||||||
alternateNames: string | null;
|
|
||||||
countryCode: string;
|
|
||||||
id: number;
|
|
||||||
latitude: number;
|
|
||||||
longitude: number;
|
|
||||||
modificationDate: Timestamp;
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Libraries {
|
|
||||||
createdAt: Generated<Timestamp>;
|
|
||||||
deletedAt: Timestamp | null;
|
|
||||||
exclusionPatterns: string[];
|
|
||||||
id: Generated<string>;
|
|
||||||
importPaths: string[];
|
|
||||||
name: string;
|
|
||||||
ownerId: string;
|
|
||||||
refreshedAt: Timestamp | null;
|
|
||||||
updatedAt: Generated<Timestamp>;
|
|
||||||
updateId: Generated<string>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Memories {
|
|
||||||
createdAt: Generated<Timestamp>;
|
|
||||||
data: object;
|
|
||||||
deletedAt: Timestamp | null;
|
|
||||||
hideAt: Timestamp | null;
|
|
||||||
id: Generated<string>;
|
|
||||||
isSaved: Generated<boolean>;
|
|
||||||
memoryAt: Timestamp;
|
|
||||||
ownerId: string;
|
|
||||||
seenAt: Timestamp | null;
|
|
||||||
showAt: Timestamp | null;
|
|
||||||
type: MemoryType;
|
|
||||||
updatedAt: Generated<Timestamp>;
|
|
||||||
updateId: Generated<string>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Notifications {
|
|
||||||
id: Generated<string>;
|
|
||||||
createdAt: Generated<Timestamp>;
|
|
||||||
updatedAt: Generated<Timestamp>;
|
|
||||||
deletedAt: Timestamp | null;
|
|
||||||
updateId: Generated<string>;
|
|
||||||
userId: string;
|
|
||||||
level: Generated<NotificationLevel>;
|
|
||||||
type: NotificationType;
|
|
||||||
title: string;
|
|
||||||
description: string | null;
|
|
||||||
data: any | null;
|
|
||||||
readAt: Timestamp | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Migrations {
|
|
||||||
id: Generated<number>;
|
|
||||||
name: string;
|
|
||||||
timestamp: Int8;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MoveHistory {
|
|
||||||
entityId: string;
|
|
||||||
id: Generated<string>;
|
|
||||||
newPath: string;
|
|
||||||
oldPath: string;
|
|
||||||
pathType: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface NaturalearthCountries {
|
|
||||||
admin: string;
|
|
||||||
admin_a3: string;
|
|
||||||
coordinates: string;
|
|
||||||
id: Generated<number>;
|
|
||||||
type: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PartnersAudit {
|
|
||||||
deletedAt: Generated<Timestamp>;
|
|
||||||
id: Generated<string>;
|
|
||||||
sharedById: string;
|
|
||||||
sharedWithId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Partners {
|
|
||||||
createdAt: Generated<Timestamp>;
|
|
||||||
createId: Generated<string>;
|
|
||||||
inTimeline: Generated<boolean>;
|
|
||||||
sharedById: string;
|
|
||||||
sharedWithId: string;
|
|
||||||
updatedAt: Generated<Timestamp>;
|
|
||||||
updateId: Generated<string>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Person {
|
|
||||||
birthDate: Timestamp | null;
|
|
||||||
color: string | null;
|
|
||||||
createdAt: Generated<Timestamp>;
|
|
||||||
faceAssetId: string | null;
|
|
||||||
id: Generated<string>;
|
|
||||||
isFavorite: Generated<boolean>;
|
|
||||||
isHidden: Generated<boolean>;
|
|
||||||
name: Generated<string>;
|
|
||||||
ownerId: string;
|
|
||||||
thumbnailPath: Generated<string>;
|
|
||||||
updatedAt: Generated<Timestamp>;
|
|
||||||
updateId: Generated<string>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Sessions {
|
|
||||||
createdAt: Generated<Timestamp>;
|
|
||||||
deviceOS: Generated<string>;
|
|
||||||
deviceType: Generated<string>;
|
|
||||||
id: Generated<string>;
|
|
||||||
parentId: string | null;
|
|
||||||
expiresAt: Date | null;
|
|
||||||
token: string;
|
|
||||||
updatedAt: Generated<Timestamp>;
|
|
||||||
updateId: Generated<string>;
|
|
||||||
userId: string;
|
|
||||||
pinExpiresAt: Timestamp | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SessionSyncCheckpoints {
|
|
||||||
ack: string;
|
|
||||||
createdAt: Generated<Timestamp>;
|
|
||||||
sessionId: string;
|
|
||||||
type: SyncEntityType;
|
|
||||||
updatedAt: Generated<Timestamp>;
|
|
||||||
updateId: Generated<string>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SharedLinkAsset {
|
|
||||||
assetsId: string;
|
|
||||||
sharedLinksId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SharedLinks {
|
|
||||||
albumId: string | null;
|
|
||||||
allowDownload: Generated<boolean>;
|
|
||||||
allowUpload: Generated<boolean>;
|
|
||||||
createdAt: Generated<Timestamp>;
|
|
||||||
description: string | null;
|
|
||||||
expiresAt: Timestamp | null;
|
|
||||||
id: Generated<string>;
|
|
||||||
key: Buffer;
|
|
||||||
password: string | null;
|
|
||||||
showExif: Generated<boolean>;
|
|
||||||
type: SharedLinkType;
|
|
||||||
userId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SmartSearch {
|
|
||||||
assetId: string;
|
|
||||||
embedding: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SocketIoAttachments {
|
|
||||||
created_at: Generated<Timestamp | null>;
|
|
||||||
id: Generated<Int8>;
|
|
||||||
payload: Buffer | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SystemConfig {
|
|
||||||
key: string;
|
|
||||||
value: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SystemMetadata {
|
|
||||||
key: string;
|
|
||||||
value: Json;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TagAsset {
|
|
||||||
assetsId: string;
|
|
||||||
tagsId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Tags {
|
|
||||||
color: string | null;
|
|
||||||
createdAt: Generated<Timestamp>;
|
|
||||||
id: Generated<string>;
|
|
||||||
parentId: string | null;
|
|
||||||
updatedAt: Generated<Timestamp>;
|
|
||||||
updateId: Generated<string>;
|
|
||||||
userId: string;
|
|
||||||
value: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TagsClosure {
|
|
||||||
id_ancestor: string;
|
|
||||||
id_descendant: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TypeormMetadata {
|
|
||||||
database: string | null;
|
|
||||||
name: string | null;
|
|
||||||
schema: string | null;
|
|
||||||
table: string | null;
|
|
||||||
type: string;
|
|
||||||
value: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface UserMetadata extends UserMetadataItem {
|
|
||||||
userId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface UsersAudit {
|
|
||||||
id: Generated<string>;
|
|
||||||
userId: string;
|
|
||||||
deletedAt: Generated<Timestamp>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface VectorsPgVectorIndexStat {
|
|
||||||
idx_growing: ArrayType<Int8> | null;
|
|
||||||
idx_indexing: boolean | null;
|
|
||||||
idx_options: string | null;
|
|
||||||
idx_sealed: ArrayType<Int8> | null;
|
|
||||||
idx_size: Int8 | null;
|
|
||||||
idx_status: string | null;
|
|
||||||
idx_tuples: Int8 | null;
|
|
||||||
idx_write: Int8 | null;
|
|
||||||
indexname: string | null;
|
|
||||||
indexrelid: number | null;
|
|
||||||
tablename: string | null;
|
|
||||||
tablerelid: number | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface VersionHistory {
|
|
||||||
createdAt: Generated<Timestamp>;
|
|
||||||
id: Generated<string>;
|
|
||||||
version: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DB {
|
|
||||||
activity: Activity;
|
|
||||||
albums: Albums;
|
|
||||||
albums_audit: AlbumsAudit;
|
|
||||||
albums_assets_assets: AlbumsAssetsAssets;
|
|
||||||
album_assets_audit: AlbumAssetsAudit;
|
|
||||||
albums_shared_users_users: AlbumsSharedUsersUsers;
|
|
||||||
album_users_audit: AlbumUsersAudit;
|
|
||||||
api_keys: ApiKeys;
|
|
||||||
asset_faces: AssetFaces;
|
|
||||||
asset_files: AssetFiles;
|
|
||||||
asset_job_status: AssetJobStatus;
|
|
||||||
asset_stack: AssetStack;
|
|
||||||
assets: Assets;
|
|
||||||
assets_audit: AssetsAudit;
|
|
||||||
audit: Audit;
|
|
||||||
exif: Exif;
|
|
||||||
face_search: FaceSearch;
|
|
||||||
geodata_places: GeodataPlaces;
|
|
||||||
libraries: Libraries;
|
|
||||||
memories: Memories;
|
|
||||||
memories_audit: MemoryAuditTable;
|
|
||||||
memories_assets_assets: MemoryAssetTable;
|
|
||||||
memory_assets_audit: MemoryAssetAuditTable;
|
|
||||||
migrations: Migrations;
|
|
||||||
notifications: Notifications;
|
|
||||||
move_history: MoveHistory;
|
|
||||||
naturalearth_countries: NaturalearthCountries;
|
|
||||||
partners_audit: PartnersAudit;
|
|
||||||
partners: Partners;
|
|
||||||
person: Person;
|
|
||||||
sessions: Sessions;
|
|
||||||
session_sync_checkpoints: SessionSyncCheckpoints;
|
|
||||||
shared_link__asset: SharedLinkAsset;
|
|
||||||
shared_links: SharedLinks;
|
|
||||||
smart_search: SmartSearch;
|
|
||||||
socket_io_attachments: SocketIoAttachments;
|
|
||||||
system_config: SystemConfig;
|
|
||||||
system_metadata: SystemMetadata;
|
|
||||||
tag_asset: TagAsset;
|
|
||||||
tags: Tags;
|
|
||||||
tags_closure: TagsClosure;
|
|
||||||
typeorm_metadata: TypeormMetadata;
|
|
||||||
user_metadata: UserMetadata;
|
|
||||||
users: UserTable;
|
|
||||||
users_audit: UsersAudit;
|
|
||||||
'vectors.pg_vector_index_stat': VectorsPgVectorIndexStat;
|
|
||||||
version_history: VersionHistory;
|
|
||||||
}
|
|
@ -4,10 +4,10 @@ import { IsArray, IsInt, IsNotEmpty, IsNumber, IsString, Max, Min, ValidateNeste
|
|||||||
import { Selectable } from 'kysely';
|
import { Selectable } from 'kysely';
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import { AssetFace, Person } from 'src/database';
|
import { AssetFace, Person } from 'src/database';
|
||||||
import { AssetFaces } from 'src/db';
|
|
||||||
import { PropertyLifecycle } from 'src/decorators';
|
import { PropertyLifecycle } from 'src/decorators';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import { SourceType } from 'src/enum';
|
import { SourceType } from 'src/enum';
|
||||||
|
import { AssetFaceTable } from 'src/schema/tables/asset-face.table';
|
||||||
import { asDateString } from 'src/utils/date';
|
import { asDateString } from 'src/utils/date';
|
||||||
import {
|
import {
|
||||||
IsDateStringFormat,
|
IsDateStringFormat,
|
||||||
@ -232,7 +232,7 @@ export function mapPerson(person: Person): PersonResponseDto {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mapFacesWithoutPerson(face: Selectable<AssetFaces>): AssetFaceWithoutPersonResponseDto {
|
export function mapFacesWithoutPerson(face: Selectable<AssetFaceTable>): AssetFaceWithoutPersonResponseDto {
|
||||||
return {
|
return {
|
||||||
id: face.id,
|
id: face.id,
|
||||||
imageHeight: face.imageHeight,
|
imageHeight: face.imageHeight,
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { Kysely, sql } from 'kysely';
|
import { Kysely, sql } from 'kysely';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { ChunkedSet, DummyValue, GenerateSql } from 'src/decorators';
|
import { ChunkedSet, DummyValue, GenerateSql } from 'src/decorators';
|
||||||
import { AlbumUserRole, AssetVisibility } from 'src/enum';
|
import { AlbumUserRole, AssetVisibility } from 'src/enum';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
import { asUuid } from 'src/utils/database';
|
import { asUuid } from 'src/utils/database';
|
||||||
|
|
||||||
class ActivityAccess {
|
class ActivityAccess {
|
||||||
|
@ -3,9 +3,10 @@ import { Insertable, Kysely, NotNull, sql } from 'kysely';
|
|||||||
import { jsonObjectFrom } from 'kysely/helpers/postgres';
|
import { jsonObjectFrom } from 'kysely/helpers/postgres';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { columns } from 'src/database';
|
import { columns } from 'src/database';
|
||||||
import { Activity, DB } from 'src/db';
|
|
||||||
import { DummyValue, GenerateSql } from 'src/decorators';
|
import { DummyValue, GenerateSql } from 'src/decorators';
|
||||||
import { AssetVisibility } from 'src/enum';
|
import { AssetVisibility } from 'src/enum';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
|
import { ActivityTable } from 'src/schema/tables/activity.table';
|
||||||
import { asUuid } from 'src/utils/database';
|
import { asUuid } from 'src/utils/database';
|
||||||
|
|
||||||
export interface ActivitySearch {
|
export interface ActivitySearch {
|
||||||
@ -48,7 +49,7 @@ export class ActivityRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GenerateSql({ params: [{ albumId: DummyValue.UUID, userId: DummyValue.UUID }] })
|
@GenerateSql({ params: [{ albumId: DummyValue.UUID, userId: DummyValue.UUID }] })
|
||||||
async create(activity: Insertable<Activity>) {
|
async create(activity: Insertable<ActivityTable>) {
|
||||||
return this.db
|
return this.db
|
||||||
.insertInto('activity')
|
.insertInto('activity')
|
||||||
.values(activity)
|
.values(activity)
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { Insertable, Kysely, Updateable } from 'kysely';
|
import { Insertable, Kysely, Updateable } from 'kysely';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { AlbumsSharedUsersUsers, DB } from 'src/db';
|
|
||||||
import { DummyValue, GenerateSql } from 'src/decorators';
|
import { DummyValue, GenerateSql } from 'src/decorators';
|
||||||
import { AlbumUserRole } from 'src/enum';
|
import { AlbumUserRole } from 'src/enum';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
|
import { AlbumUserTable } from 'src/schema/tables/album-user.table';
|
||||||
|
|
||||||
export type AlbumPermissionId = {
|
export type AlbumPermissionId = {
|
||||||
albumsId: string;
|
albumsId: string;
|
||||||
@ -15,7 +16,7 @@ export class AlbumUserRepository {
|
|||||||
constructor(@InjectKysely() private db: Kysely<DB>) {}
|
constructor(@InjectKysely() private db: Kysely<DB>) {}
|
||||||
|
|
||||||
@GenerateSql({ params: [{ usersId: DummyValue.UUID, albumsId: DummyValue.UUID }] })
|
@GenerateSql({ params: [{ usersId: DummyValue.UUID, albumsId: DummyValue.UUID }] })
|
||||||
create(albumUser: Insertable<AlbumsSharedUsersUsers>) {
|
create(albumUser: Insertable<AlbumUserTable>) {
|
||||||
return this.db
|
return this.db
|
||||||
.insertInto('albums_shared_users_users')
|
.insertInto('albums_shared_users_users')
|
||||||
.values(albumUser)
|
.values(albumUser)
|
||||||
@ -24,7 +25,7 @@ export class AlbumUserRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GenerateSql({ params: [{ usersId: DummyValue.UUID, albumsId: DummyValue.UUID }, { role: AlbumUserRole.VIEWER }] })
|
@GenerateSql({ params: [{ usersId: DummyValue.UUID, albumsId: DummyValue.UUID }, { role: AlbumUserRole.VIEWER }] })
|
||||||
update({ usersId, albumsId }: AlbumPermissionId, dto: Updateable<AlbumsSharedUsersUsers>) {
|
update({ usersId, albumsId }: AlbumPermissionId, dto: Updateable<AlbumUserTable>) {
|
||||||
return this.db
|
return this.db
|
||||||
.updateTable('albums_shared_users_users')
|
.updateTable('albums_shared_users_users')
|
||||||
.set(dto)
|
.set(dto)
|
||||||
|
@ -3,9 +3,10 @@ import { ExpressionBuilder, Insertable, Kysely, NotNull, sql, Updateable } from
|
|||||||
import { jsonArrayFrom, jsonObjectFrom } from 'kysely/helpers/postgres';
|
import { jsonArrayFrom, jsonObjectFrom } from 'kysely/helpers/postgres';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { columns, Exif } from 'src/database';
|
import { columns, Exif } from 'src/database';
|
||||||
import { Albums, DB } from 'src/db';
|
|
||||||
import { Chunked, ChunkedArray, ChunkedSet, DummyValue, GenerateSql } from 'src/decorators';
|
import { Chunked, ChunkedArray, ChunkedSet, DummyValue, GenerateSql } from 'src/decorators';
|
||||||
import { AlbumUserCreateDto } from 'src/dtos/album.dto';
|
import { AlbumUserCreateDto } from 'src/dtos/album.dto';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
|
import { AlbumTable } from 'src/schema/tables/album.table';
|
||||||
import { withDefaultVisibility } from 'src/utils/database';
|
import { withDefaultVisibility } from 'src/utils/database';
|
||||||
|
|
||||||
export interface AlbumAssetCount {
|
export interface AlbumAssetCount {
|
||||||
@ -269,7 +270,7 @@ export class AlbumRepository {
|
|||||||
await this.addAssets(this.db, albumId, assetIds);
|
await this.addAssets(this.db, albumId, assetIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
create(album: Insertable<Albums>, assetIds: string[], albumUsers: AlbumUserCreateDto[]) {
|
create(album: Insertable<AlbumTable>, assetIds: string[], albumUsers: AlbumUserCreateDto[]) {
|
||||||
return this.db.transaction().execute(async (tx) => {
|
return this.db.transaction().execute(async (tx) => {
|
||||||
const newAlbum = await tx.insertInto('albums').values(album).returning('albums.id').executeTakeFirst();
|
const newAlbum = await tx.insertInto('albums').values(album).returning('albums.id').executeTakeFirst();
|
||||||
|
|
||||||
@ -302,7 +303,7 @@ export class AlbumRepository {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
update(id: string, album: Updateable<Albums>) {
|
update(id: string, album: Updateable<AlbumTable>) {
|
||||||
return this.db
|
return this.db
|
||||||
.updateTable('albums')
|
.updateTable('albums')
|
||||||
.set(album)
|
.set(album)
|
||||||
|
@ -3,19 +3,20 @@ import { Insertable, Kysely, Updateable } from 'kysely';
|
|||||||
import { jsonObjectFrom } from 'kysely/helpers/postgres';
|
import { jsonObjectFrom } from 'kysely/helpers/postgres';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { columns } from 'src/database';
|
import { columns } from 'src/database';
|
||||||
import { ApiKeys, DB } from 'src/db';
|
|
||||||
import { DummyValue, GenerateSql } from 'src/decorators';
|
import { DummyValue, GenerateSql } from 'src/decorators';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
|
import { ApiKeyTable } from 'src/schema/tables/api-key.table';
|
||||||
import { asUuid } from 'src/utils/database';
|
import { asUuid } from 'src/utils/database';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ApiKeyRepository {
|
export class ApiKeyRepository {
|
||||||
constructor(@InjectKysely() private db: Kysely<DB>) {}
|
constructor(@InjectKysely() private db: Kysely<DB>) {}
|
||||||
|
|
||||||
create(dto: Insertable<ApiKeys>) {
|
create(dto: Insertable<ApiKeyTable>) {
|
||||||
return this.db.insertInto('api_keys').values(dto).returning(columns.apiKey).executeTakeFirstOrThrow();
|
return this.db.insertInto('api_keys').values(dto).returning(columns.apiKey).executeTakeFirstOrThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(userId: string, id: string, dto: Updateable<ApiKeys>) {
|
async update(userId: string, id: string, dto: Updateable<ApiKeyTable>) {
|
||||||
return this.db
|
return this.db
|
||||||
.updateTable('api_keys')
|
.updateTable('api_keys')
|
||||||
.set(dto)
|
.set(dto)
|
||||||
|
@ -3,9 +3,9 @@ import { Kysely } from 'kysely';
|
|||||||
import { jsonArrayFrom } from 'kysely/helpers/postgres';
|
import { jsonArrayFrom } from 'kysely/helpers/postgres';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { Asset, columns } from 'src/database';
|
import { Asset, columns } from 'src/database';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { DummyValue, GenerateSql } from 'src/decorators';
|
import { DummyValue, GenerateSql } from 'src/decorators';
|
||||||
import { AssetFileType, AssetType, AssetVisibility } from 'src/enum';
|
import { AssetFileType, AssetType, AssetVisibility } from 'src/enum';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
import { StorageAsset } from 'src/types';
|
import { StorageAsset } from 'src/types';
|
||||||
import {
|
import {
|
||||||
anyUuid,
|
anyUuid,
|
||||||
|
@ -3,9 +3,13 @@ import { Insertable, Kysely, NotNull, Selectable, UpdateResult, Updateable, sql
|
|||||||
import { isEmpty, isUndefined, omitBy } from 'lodash';
|
import { isEmpty, isUndefined, omitBy } from 'lodash';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { Stack } from 'src/database';
|
import { Stack } from 'src/database';
|
||||||
import { AssetFiles, AssetJobStatus, Assets, DB, Exif } from 'src/db';
|
|
||||||
import { Chunked, ChunkedArray, DummyValue, GenerateSql } from 'src/decorators';
|
import { Chunked, ChunkedArray, DummyValue, GenerateSql } from 'src/decorators';
|
||||||
import { AssetFileType, AssetOrder, AssetStatus, AssetType, AssetVisibility } from 'src/enum';
|
import { AssetFileType, AssetOrder, AssetStatus, AssetType, AssetVisibility } from 'src/enum';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
|
import { AssetFileTable } from 'src/schema/tables/asset-files.table';
|
||||||
|
import { AssetJobStatusTable } from 'src/schema/tables/asset-job-status.table';
|
||||||
|
import { AssetTable } from 'src/schema/tables/asset.table';
|
||||||
|
import { ExifTable } from 'src/schema/tables/exif.table';
|
||||||
import {
|
import {
|
||||||
anyUuid,
|
anyUuid,
|
||||||
asUuid,
|
asUuid,
|
||||||
@ -110,7 +114,7 @@ interface GetByIdsRelations {
|
|||||||
export class AssetRepository {
|
export class AssetRepository {
|
||||||
constructor(@InjectKysely() private db: Kysely<DB>) {}
|
constructor(@InjectKysely() private db: Kysely<DB>) {}
|
||||||
|
|
||||||
async upsertExif(exif: Insertable<Exif>): Promise<void> {
|
async upsertExif(exif: Insertable<ExifTable>): Promise<void> {
|
||||||
const value = { ...exif, assetId: asUuid(exif.assetId) };
|
const value = { ...exif, assetId: asUuid(exif.assetId) };
|
||||||
await this.db
|
await this.db
|
||||||
.insertInto('exif')
|
.insertInto('exif')
|
||||||
@ -157,7 +161,7 @@ export class AssetRepository {
|
|||||||
|
|
||||||
@GenerateSql({ params: [[DummyValue.UUID], { model: DummyValue.STRING }] })
|
@GenerateSql({ params: [[DummyValue.UUID], { model: DummyValue.STRING }] })
|
||||||
@Chunked()
|
@Chunked()
|
||||||
async updateAllExif(ids: string[], options: Updateable<Exif>): Promise<void> {
|
async updateAllExif(ids: string[], options: Updateable<ExifTable>): Promise<void> {
|
||||||
if (ids.length === 0) {
|
if (ids.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -165,7 +169,7 @@ export class AssetRepository {
|
|||||||
await this.db.updateTable('exif').set(options).where('assetId', 'in', ids).execute();
|
await this.db.updateTable('exif').set(options).where('assetId', 'in', ids).execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
async upsertJobStatus(...jobStatus: Insertable<AssetJobStatus>[]): Promise<void> {
|
async upsertJobStatus(...jobStatus: Insertable<AssetJobStatusTable>[]): Promise<void> {
|
||||||
if (jobStatus.length === 0) {
|
if (jobStatus.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -191,11 +195,11 @@ export class AssetRepository {
|
|||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
create(asset: Insertable<Assets>) {
|
create(asset: Insertable<AssetTable>) {
|
||||||
return this.db.insertInto('assets').values(asset).returningAll().executeTakeFirstOrThrow();
|
return this.db.insertInto('assets').values(asset).returningAll().executeTakeFirstOrThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
createAll(assets: Insertable<Assets>[]) {
|
createAll(assets: Insertable<AssetTable>[]) {
|
||||||
return this.db.insertInto('assets').values(assets).returningAll().execute();
|
return this.db.insertInto('assets').values(assets).returningAll().execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,18 +379,18 @@ export class AssetRepository {
|
|||||||
|
|
||||||
@GenerateSql({ params: [[DummyValue.UUID], { deviceId: DummyValue.STRING }] })
|
@GenerateSql({ params: [[DummyValue.UUID], { deviceId: DummyValue.STRING }] })
|
||||||
@Chunked()
|
@Chunked()
|
||||||
async updateAll(ids: string[], options: Updateable<Assets>): Promise<void> {
|
async updateAll(ids: string[], options: Updateable<AssetTable>): Promise<void> {
|
||||||
if (ids.length === 0) {
|
if (ids.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await this.db.updateTable('assets').set(options).where('id', '=', anyUuid(ids)).execute();
|
await this.db.updateTable('assets').set(options).where('id', '=', anyUuid(ids)).execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateByLibraryId(libraryId: string, options: Updateable<Assets>): Promise<void> {
|
async updateByLibraryId(libraryId: string, options: Updateable<AssetTable>): Promise<void> {
|
||||||
await this.db.updateTable('assets').set(options).where('libraryId', '=', asUuid(libraryId)).execute();
|
await this.db.updateTable('assets').set(options).where('libraryId', '=', asUuid(libraryId)).execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(asset: Updateable<Assets> & { id: string }) {
|
async update(asset: Updateable<AssetTable> & { id: string }) {
|
||||||
const value = omitBy(asset, isUndefined);
|
const value = omitBy(asset, isUndefined);
|
||||||
delete value.id;
|
delete value.id;
|
||||||
if (!isEmpty(value)) {
|
if (!isEmpty(value)) {
|
||||||
@ -742,7 +746,7 @@ export class AssetRepository {
|
|||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
async upsertFile(file: Pick<Insertable<AssetFiles>, 'assetId' | 'path' | 'type'>): Promise<void> {
|
async upsertFile(file: Pick<Insertable<AssetFileTable>, 'assetId' | 'path' | 'type'>): Promise<void> {
|
||||||
const value = { ...file, assetId: asUuid(file.assetId) };
|
const value = { ...file, assetId: asUuid(file.assetId) };
|
||||||
await this.db
|
await this.db
|
||||||
.insertInto('asset_files')
|
.insertInto('asset_files')
|
||||||
@ -755,7 +759,7 @@ export class AssetRepository {
|
|||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
async upsertFiles(files: Pick<Insertable<AssetFiles>, 'assetId' | 'path' | 'type'>[]): Promise<void> {
|
async upsertFiles(files: Pick<Insertable<AssetFileTable>, 'assetId' | 'path' | 'type'>[]): Promise<void> {
|
||||||
if (files.length === 0) {
|
if (files.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -772,7 +776,7 @@ export class AssetRepository {
|
|||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteFiles(files: Pick<Selectable<AssetFiles>, 'id'>[]): Promise<void> {
|
async deleteFiles(files: Pick<Selectable<AssetFileTable>, 'id'>[]): Promise<void> {
|
||||||
if (files.length === 0) {
|
if (files.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { Kysely } from 'kysely';
|
import { Kysely } from 'kysely';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { DummyValue, GenerateSql } from 'src/decorators';
|
import { DummyValue, GenerateSql } from 'src/decorators';
|
||||||
import { DatabaseAction, EntityType } from 'src/enum';
|
import { DatabaseAction, EntityType } from 'src/enum';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
|
|
||||||
export interface AuditSearch {
|
export interface AuditSearch {
|
||||||
action?: DatabaseAction;
|
action?: DatabaseAction;
|
||||||
|
@ -15,11 +15,11 @@ import {
|
|||||||
VECTORCHORD_VERSION_RANGE,
|
VECTORCHORD_VERSION_RANGE,
|
||||||
VECTORS_VERSION_RANGE,
|
VECTORS_VERSION_RANGE,
|
||||||
} from 'src/constants';
|
} from 'src/constants';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { GenerateSql } from 'src/decorators';
|
import { GenerateSql } from 'src/decorators';
|
||||||
import { DatabaseExtension, DatabaseLock, VectorIndex } from 'src/enum';
|
import { DatabaseExtension, DatabaseLock, VectorIndex } from 'src/enum';
|
||||||
import { ConfigRepository } from 'src/repositories/config.repository';
|
import { ConfigRepository } from 'src/repositories/config.repository';
|
||||||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
import { ExtensionVersion, VectorExtension, VectorUpdateResult } from 'src/types';
|
import { ExtensionVersion, VectorExtension, VectorUpdateResult } from 'src/types';
|
||||||
import { vectorIndexQuery } from 'src/utils/database';
|
import { vectorIndexQuery } from 'src/utils/database';
|
||||||
import { isValidInteger } from 'src/validation';
|
import { isValidInteger } from 'src/validation';
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { Kysely } from 'kysely';
|
import { Kysely } from 'kysely';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { AssetVisibility } from 'src/enum';
|
import { AssetVisibility } from 'src/enum';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
import { anyUuid } from 'src/utils/database';
|
import { anyUuid } from 'src/utils/database';
|
||||||
|
|
||||||
const builder = (db: Kysely<DB>) =>
|
const builder = (db: Kysely<DB>) =>
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { Kysely, NotNull, sql } from 'kysely';
|
import { Kysely, NotNull, sql } from 'kysely';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { Chunked, DummyValue, GenerateSql } from 'src/decorators';
|
import { Chunked, DummyValue, GenerateSql } from 'src/decorators';
|
||||||
import { MapAsset } from 'src/dtos/asset-response.dto';
|
import { MapAsset } from 'src/dtos/asset-response.dto';
|
||||||
import { AssetType, VectorIndex } from 'src/enum';
|
import { AssetType, VectorIndex } from 'src/enum';
|
||||||
import { probes } from 'src/repositories/database.repository';
|
import { probes } from 'src/repositories/database.repository';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
import { anyUuid, asUuid, withDefaultVisibility } from 'src/utils/database';
|
import { anyUuid, asUuid, withDefaultVisibility } from 'src/utils/database';
|
||||||
|
|
||||||
interface DuplicateSearch {
|
interface DuplicateSearch {
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { Insertable, Kysely, sql, Updateable } from 'kysely';
|
import { Insertable, Kysely, sql, Updateable } from 'kysely';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { DB, Libraries } from 'src/db';
|
|
||||||
import { DummyValue, GenerateSql } from 'src/decorators';
|
import { DummyValue, GenerateSql } from 'src/decorators';
|
||||||
import { LibraryStatsResponseDto } from 'src/dtos/library.dto';
|
import { LibraryStatsResponseDto } from 'src/dtos/library.dto';
|
||||||
import { AssetType, AssetVisibility } from 'src/enum';
|
import { AssetType, AssetVisibility } from 'src/enum';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
|
import { LibraryTable } from 'src/schema/tables/library.table';
|
||||||
|
|
||||||
export enum AssetSyncResult {
|
export enum AssetSyncResult {
|
||||||
DO_NOTHING,
|
DO_NOTHING,
|
||||||
@ -47,7 +48,7 @@ export class LibraryRepository {
|
|||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
create(library: Insertable<Libraries>) {
|
create(library: Insertable<LibraryTable>) {
|
||||||
return this.db.insertInto('libraries').values(library).returningAll().executeTakeFirstOrThrow();
|
return this.db.insertInto('libraries').values(library).returningAll().executeTakeFirstOrThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +60,7 @@ export class LibraryRepository {
|
|||||||
await this.db.updateTable('libraries').set({ deletedAt: new Date() }).where('libraries.id', '=', id).execute();
|
await this.db.updateTable('libraries').set({ deletedAt: new Date() }).where('libraries.id', '=', id).execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
update(id: string, library: Updateable<Libraries>) {
|
update(id: string, library: Updateable<LibraryTable>) {
|
||||||
return this.db
|
return this.db
|
||||||
.updateTable('libraries')
|
.updateTable('libraries')
|
||||||
.set(library)
|
.set(library)
|
||||||
|
@ -6,12 +6,14 @@ import { createReadStream, existsSync } from 'node:fs';
|
|||||||
import { readFile } from 'node:fs/promises';
|
import { readFile } from 'node:fs/promises';
|
||||||
import readLine from 'node:readline';
|
import readLine from 'node:readline';
|
||||||
import { citiesFile } from 'src/constants';
|
import { citiesFile } from 'src/constants';
|
||||||
import { DB, GeodataPlaces, NaturalearthCountries } from 'src/db';
|
|
||||||
import { DummyValue, GenerateSql } from 'src/decorators';
|
import { DummyValue, GenerateSql } from 'src/decorators';
|
||||||
import { AssetVisibility, SystemMetadataKey } from 'src/enum';
|
import { AssetVisibility, SystemMetadataKey } from 'src/enum';
|
||||||
import { ConfigRepository } from 'src/repositories/config.repository';
|
import { ConfigRepository } from 'src/repositories/config.repository';
|
||||||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||||
import { SystemMetadataRepository } from 'src/repositories/system-metadata.repository';
|
import { SystemMetadataRepository } from 'src/repositories/system-metadata.repository';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
|
import { GeodataPlacesTable } from 'src/schema/tables/geodata-places.table';
|
||||||
|
import { NaturalEarthCountriesTable } from 'src/schema/tables/natural-earth-countries.table';
|
||||||
|
|
||||||
export interface MapMarkerSearchOptions {
|
export interface MapMarkerSearchOptions {
|
||||||
isArchived?: boolean;
|
isArchived?: boolean;
|
||||||
@ -38,8 +40,8 @@ export interface MapMarker extends ReverseGeocodeResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface MapDB extends DB {
|
interface MapDB extends DB {
|
||||||
geodata_places_tmp: GeodataPlaces;
|
geodata_places_tmp: GeodataPlacesTable;
|
||||||
naturalearth_countries_tmp: NaturalearthCountries;
|
naturalearth_countries_tmp: NaturalEarthCountriesTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -193,11 +195,11 @@ export class MapRepository {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const entities: Insertable<NaturalearthCountries>[] = [];
|
const entities: Insertable<NaturalEarthCountriesTable>[] = [];
|
||||||
for (const feature of geoJSONData.features) {
|
for (const feature of geoJSONData.features) {
|
||||||
for (const entry of feature.geometry.coordinates) {
|
for (const entry of feature.geometry.coordinates) {
|
||||||
const coordinates: number[][][] = feature.geometry.type === 'MultiPolygon' ? entry[0] : entry;
|
const coordinates: number[][][] = feature.geometry.type === 'MultiPolygon' ? entry[0] : entry;
|
||||||
const featureRecord: Insertable<NaturalearthCountries> = {
|
const featureRecord: Insertable<NaturalEarthCountriesTable> = {
|
||||||
admin: feature.properties.ADMIN,
|
admin: feature.properties.ADMIN,
|
||||||
admin_a3: feature.properties.ADM0_A3,
|
admin_a3: feature.properties.ADM0_A3,
|
||||||
type: feature.properties.TYPE,
|
type: feature.properties.TYPE,
|
||||||
|
@ -3,10 +3,11 @@ import { Insertable, Kysely, sql, Updateable } from 'kysely';
|
|||||||
import { jsonArrayFrom } from 'kysely/helpers/postgres';
|
import { jsonArrayFrom } from 'kysely/helpers/postgres';
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { DB, Memories } from 'src/db';
|
|
||||||
import { Chunked, ChunkedSet, DummyValue, GenerateSql } from 'src/decorators';
|
import { Chunked, ChunkedSet, DummyValue, GenerateSql } from 'src/decorators';
|
||||||
import { MemorySearchDto } from 'src/dtos/memory.dto';
|
import { MemorySearchDto } from 'src/dtos/memory.dto';
|
||||||
import { AssetVisibility } from 'src/enum';
|
import { AssetVisibility } from 'src/enum';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
|
import { MemoryTable } from 'src/schema/tables/memory.table';
|
||||||
import { IBulkAsset } from 'src/types';
|
import { IBulkAsset } from 'src/types';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -80,7 +81,7 @@ export class MemoryRepository implements IBulkAsset {
|
|||||||
return this.getByIdBuilder(id).executeTakeFirst();
|
return this.getByIdBuilder(id).executeTakeFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(memory: Insertable<Memories>, assetIds: Set<string>) {
|
async create(memory: Insertable<MemoryTable>, assetIds: Set<string>) {
|
||||||
const id = await this.db.transaction().execute(async (tx) => {
|
const id = await this.db.transaction().execute(async (tx) => {
|
||||||
const { id } = await tx.insertInto('memories').values(memory).returning('id').executeTakeFirstOrThrow();
|
const { id } = await tx.insertInto('memories').values(memory).returning('id').executeTakeFirstOrThrow();
|
||||||
|
|
||||||
@ -96,7 +97,7 @@ export class MemoryRepository implements IBulkAsset {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GenerateSql({ params: [DummyValue.UUID, { ownerId: DummyValue.UUID, isSaved: true }] })
|
@GenerateSql({ params: [DummyValue.UUID, { ownerId: DummyValue.UUID, isSaved: true }] })
|
||||||
async update(id: string, memory: Updateable<Memories>) {
|
async update(id: string, memory: Updateable<MemoryTable>) {
|
||||||
await this.db.updateTable('memories').set(memory).where('id', '=', id).execute();
|
await this.db.updateTable('memories').set(memory).where('id', '=', id).execute();
|
||||||
return this.getByIdBuilder(id).executeTakeFirstOrThrow();
|
return this.getByIdBuilder(id).executeTakeFirstOrThrow();
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { Insertable, Kysely, sql, Updateable } from 'kysely';
|
import { Insertable, Kysely, sql, Updateable } from 'kysely';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { DB, MoveHistory } from 'src/db';
|
|
||||||
import { DummyValue, GenerateSql } from 'src/decorators';
|
import { DummyValue, GenerateSql } from 'src/decorators';
|
||||||
import { AssetPathType, PathType } from 'src/enum';
|
import { AssetPathType, PathType } from 'src/enum';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
|
import { MoveTable } from 'src/schema/tables/move.table';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class MoveRepository {
|
export class MoveRepository {
|
||||||
constructor(@InjectKysely() private db: Kysely<DB>) {}
|
constructor(@InjectKysely() private db: Kysely<DB>) {}
|
||||||
|
|
||||||
create(entity: Insertable<MoveHistory>) {
|
create(entity: Insertable<MoveTable>) {
|
||||||
return this.db.insertInto('move_history').values(entity).returningAll().executeTakeFirstOrThrow();
|
return this.db.insertInto('move_history').values(entity).returningAll().executeTakeFirstOrThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,7 +24,7 @@ export class MoveRepository {
|
|||||||
.executeTakeFirst();
|
.executeTakeFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
update(id: string, entity: Updateable<MoveHistory>) {
|
update(id: string, entity: Updateable<MoveTable>) {
|
||||||
return this.db
|
return this.db
|
||||||
.updateTable('move_history')
|
.updateTable('move_history')
|
||||||
.set(entity)
|
.set(entity)
|
||||||
|
@ -2,9 +2,10 @@ import { Insertable, Kysely, Updateable } from 'kysely';
|
|||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { columns } from 'src/database';
|
import { columns } from 'src/database';
|
||||||
import { DB, Notifications } from 'src/db';
|
|
||||||
import { DummyValue, GenerateSql } from 'src/decorators';
|
import { DummyValue, GenerateSql } from 'src/decorators';
|
||||||
import { NotificationSearchDto } from 'src/dtos/notification.dto';
|
import { NotificationSearchDto } from 'src/dtos/notification.dto';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
|
import { NotificationTable } from 'src/schema/tables/notification.table';
|
||||||
|
|
||||||
export class NotificationRepository {
|
export class NotificationRepository {
|
||||||
constructor(@InjectKysely() private db: Kysely<DB>) {}
|
constructor(@InjectKysely() private db: Kysely<DB>) {}
|
||||||
@ -53,7 +54,7 @@ export class NotificationRepository {
|
|||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
create(notification: Insertable<Notifications>) {
|
create(notification: Insertable<NotificationTable>) {
|
||||||
return this.db
|
return this.db
|
||||||
.insertInto('notifications')
|
.insertInto('notifications')
|
||||||
.values(notification)
|
.values(notification)
|
||||||
@ -70,7 +71,7 @@ export class NotificationRepository {
|
|||||||
.executeTakeFirst();
|
.executeTakeFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
update(id: string, notification: Updateable<Notifications>) {
|
update(id: string, notification: Updateable<NotificationTable>) {
|
||||||
return this.db
|
return this.db
|
||||||
.updateTable('notifications')
|
.updateTable('notifications')
|
||||||
.set(notification)
|
.set(notification)
|
||||||
@ -80,7 +81,7 @@ export class NotificationRepository {
|
|||||||
.executeTakeFirstOrThrow();
|
.executeTakeFirstOrThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateAll(ids: string[], notification: Updateable<Notifications>) {
|
async updateAll(ids: string[], notification: Updateable<NotificationTable>) {
|
||||||
await this.db.updateTable('notifications').set(notification).where('id', 'in', ids).execute();
|
await this.db.updateTable('notifications').set(notification).where('id', 'in', ids).execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,8 +3,9 @@ import { ExpressionBuilder, Insertable, Kysely, NotNull, Updateable } from 'kyse
|
|||||||
import { jsonObjectFrom } from 'kysely/helpers/postgres';
|
import { jsonObjectFrom } from 'kysely/helpers/postgres';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { columns } from 'src/database';
|
import { columns } from 'src/database';
|
||||||
import { DB, Partners } from 'src/db';
|
|
||||||
import { DummyValue, GenerateSql } from 'src/decorators';
|
import { DummyValue, GenerateSql } from 'src/decorators';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
|
import { PartnerTable } from 'src/schema/tables/partner.table';
|
||||||
|
|
||||||
export interface PartnerIds {
|
export interface PartnerIds {
|
||||||
sharedById: string;
|
sharedById: string;
|
||||||
@ -47,7 +48,7 @@ export class PartnerRepository {
|
|||||||
.executeTakeFirst();
|
.executeTakeFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
create(values: Insertable<Partners>) {
|
create(values: Insertable<PartnerTable>) {
|
||||||
return this.db
|
return this.db
|
||||||
.insertInto('partners')
|
.insertInto('partners')
|
||||||
.values(values)
|
.values(values)
|
||||||
@ -59,7 +60,7 @@ export class PartnerRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GenerateSql({ params: [{ sharedWithId: DummyValue.UUID, sharedById: DummyValue.UUID }, { inTimeline: true }] })
|
@GenerateSql({ params: [{ sharedWithId: DummyValue.UUID, sharedById: DummyValue.UUID }, { inTimeline: true }] })
|
||||||
update({ sharedWithId, sharedById }: PartnerIds, values: Updateable<Partners>) {
|
update({ sharedWithId, sharedById }: PartnerIds, values: Updateable<PartnerTable>) {
|
||||||
return this.db
|
return this.db
|
||||||
.updateTable('partners')
|
.updateTable('partners')
|
||||||
.set(values)
|
.set(values)
|
||||||
|
@ -2,9 +2,12 @@ import { Injectable } from '@nestjs/common';
|
|||||||
import { ExpressionBuilder, Insertable, Kysely, Selectable, sql, Updateable } from 'kysely';
|
import { ExpressionBuilder, Insertable, Kysely, Selectable, sql, Updateable } from 'kysely';
|
||||||
import { jsonObjectFrom } from 'kysely/helpers/postgres';
|
import { jsonObjectFrom } from 'kysely/helpers/postgres';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { AssetFaces, DB, FaceSearch, Person } from 'src/db';
|
|
||||||
import { Chunked, ChunkedArray, DummyValue, GenerateSql } from 'src/decorators';
|
import { Chunked, ChunkedArray, DummyValue, GenerateSql } from 'src/decorators';
|
||||||
import { AssetFileType, AssetVisibility, SourceType } from 'src/enum';
|
import { AssetFileType, AssetVisibility, SourceType } from 'src/enum';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
|
import { AssetFaceTable } from 'src/schema/tables/asset-face.table';
|
||||||
|
import { FaceSearchTable } from 'src/schema/tables/face-search.table';
|
||||||
|
import { PersonTable } from 'src/schema/tables/person.table';
|
||||||
import { removeUndefinedKeys } from 'src/utils/database';
|
import { removeUndefinedKeys } from 'src/utils/database';
|
||||||
import { paginationHelper, PaginationOptions } from 'src/utils/pagination';
|
import { paginationHelper, PaginationOptions } from 'src/utils/pagination';
|
||||||
|
|
||||||
@ -57,7 +60,7 @@ export interface GetAllFacesOptions {
|
|||||||
|
|
||||||
export type UnassignFacesOptions = DeleteFacesOptions;
|
export type UnassignFacesOptions = DeleteFacesOptions;
|
||||||
|
|
||||||
export type SelectFaceOptions = (keyof Selectable<AssetFaces>)[];
|
export type SelectFaceOptions = (keyof Selectable<AssetFaceTable>)[];
|
||||||
|
|
||||||
const withPerson = (eb: ExpressionBuilder<DB, 'asset_faces'>) => {
|
const withPerson = (eb: ExpressionBuilder<DB, 'asset_faces'>) => {
|
||||||
return jsonObjectFrom(
|
return jsonObjectFrom(
|
||||||
@ -378,11 +381,11 @@ export class PersonRepository {
|
|||||||
.executeTakeFirstOrThrow();
|
.executeTakeFirstOrThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
create(person: Insertable<Person>) {
|
create(person: Insertable<PersonTable>) {
|
||||||
return this.db.insertInto('person').values(person).returningAll().executeTakeFirstOrThrow();
|
return this.db.insertInto('person').values(person).returningAll().executeTakeFirstOrThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
async createAll(people: Insertable<Person>[]): Promise<string[]> {
|
async createAll(people: Insertable<PersonTable>[]): Promise<string[]> {
|
||||||
if (people.length === 0) {
|
if (people.length === 0) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@ -393,9 +396,9 @@ export class PersonRepository {
|
|||||||
|
|
||||||
@GenerateSql({ params: [[], [], [{ faceId: DummyValue.UUID, embedding: DummyValue.VECTOR }]] })
|
@GenerateSql({ params: [[], [], [{ faceId: DummyValue.UUID, embedding: DummyValue.VECTOR }]] })
|
||||||
async refreshFaces(
|
async refreshFaces(
|
||||||
facesToAdd: (Insertable<AssetFaces> & { assetId: string })[],
|
facesToAdd: (Insertable<AssetFaceTable> & { assetId: string })[],
|
||||||
faceIdsToRemove: string[],
|
faceIdsToRemove: string[],
|
||||||
embeddingsToAdd?: Insertable<FaceSearch>[],
|
embeddingsToAdd?: Insertable<FaceSearchTable>[],
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
let query = this.db;
|
let query = this.db;
|
||||||
if (facesToAdd.length > 0) {
|
if (facesToAdd.length > 0) {
|
||||||
@ -415,7 +418,7 @@ export class PersonRepository {
|
|||||||
await query.selectFrom(sql`(select 1)`.as('dummy')).execute();
|
await query.selectFrom(sql`(select 1)`.as('dummy')).execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(person: Updateable<Person> & { id: string }) {
|
async update(person: Updateable<PersonTable> & { id: string }) {
|
||||||
return this.db
|
return this.db
|
||||||
.updateTable('person')
|
.updateTable('person')
|
||||||
.set(person)
|
.set(person)
|
||||||
@ -424,7 +427,7 @@ export class PersonRepository {
|
|||||||
.executeTakeFirstOrThrow();
|
.executeTakeFirstOrThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateAll(people: Insertable<Person>[]): Promise<void> {
|
async updateAll(people: Insertable<PersonTable>[]): Promise<void> {
|
||||||
if (people.length === 0) {
|
if (people.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -496,7 +499,7 @@ export class PersonRepository {
|
|||||||
return result?.latestDate;
|
return result?.latestDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
async createAssetFace(face: Insertable<AssetFaces>): Promise<void> {
|
async createAssetFace(face: Insertable<AssetFaceTable>): Promise<void> {
|
||||||
await this.db.insertInto('asset_faces').values(face).execute();
|
await this.db.insertInto('asset_faces').values(face).execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,11 +2,12 @@ import { Injectable } from '@nestjs/common';
|
|||||||
import { Kysely, OrderByDirection, Selectable, sql } from 'kysely';
|
import { Kysely, OrderByDirection, Selectable, sql } from 'kysely';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { randomUUID } from 'node:crypto';
|
import { randomUUID } from 'node:crypto';
|
||||||
import { DB, Exif } from 'src/db';
|
|
||||||
import { DummyValue, GenerateSql } from 'src/decorators';
|
import { DummyValue, GenerateSql } from 'src/decorators';
|
||||||
import { MapAsset } from 'src/dtos/asset-response.dto';
|
import { MapAsset } from 'src/dtos/asset-response.dto';
|
||||||
import { AssetStatus, AssetType, AssetVisibility, VectorIndex } from 'src/enum';
|
import { AssetStatus, AssetType, AssetVisibility, VectorIndex } from 'src/enum';
|
||||||
import { probes } from 'src/repositories/database.repository';
|
import { probes } from 'src/repositories/database.repository';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
|
import { ExifTable } from 'src/schema/tables/exif.table';
|
||||||
import { anyUuid, searchAssetBuilder } from 'src/utils/database';
|
import { anyUuid, searchAssetBuilder } from 'src/utils/database';
|
||||||
import { paginationHelper } from 'src/utils/pagination';
|
import { paginationHelper } from 'src/utils/pagination';
|
||||||
import { isValidInteger } from 'src/validation';
|
import { isValidInteger } from 'src/validation';
|
||||||
@ -385,7 +386,7 @@ export class SearchRepository {
|
|||||||
.select((eb) =>
|
.select((eb) =>
|
||||||
eb
|
eb
|
||||||
.fn('to_jsonb', [eb.table('exif')])
|
.fn('to_jsonb', [eb.table('exif')])
|
||||||
.$castTo<Selectable<Exif>>()
|
.$castTo<Selectable<ExifTable>>()
|
||||||
.as('exifInfo'),
|
.as('exifInfo'),
|
||||||
)
|
)
|
||||||
.orderBy('exif.city')
|
.orderBy('exif.city')
|
||||||
|
@ -4,8 +4,9 @@ import { jsonObjectFrom } from 'kysely/helpers/postgres';
|
|||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { columns } from 'src/database';
|
import { columns } from 'src/database';
|
||||||
import { DB, Sessions } from 'src/db';
|
|
||||||
import { DummyValue, GenerateSql } from 'src/decorators';
|
import { DummyValue, GenerateSql } from 'src/decorators';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
|
import { SessionTable } from 'src/schema/tables/session.table';
|
||||||
import { asUuid } from 'src/utils/database';
|
import { asUuid } from 'src/utils/database';
|
||||||
|
|
||||||
export type SessionSearchOptions = { updatedBefore: Date };
|
export type SessionSearchOptions = { updatedBefore: Date };
|
||||||
@ -72,11 +73,11 @@ export class SessionRepository {
|
|||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
create(dto: Insertable<Sessions>) {
|
create(dto: Insertable<SessionTable>) {
|
||||||
return this.db.insertInto('sessions').values(dto).returningAll().executeTakeFirstOrThrow();
|
return this.db.insertInto('sessions').values(dto).returningAll().executeTakeFirstOrThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
update(id: string, dto: Updateable<Sessions>) {
|
update(id: string, dto: Updateable<SessionTable>) {
|
||||||
return this.db
|
return this.db
|
||||||
.updateTable('sessions')
|
.updateTable('sessions')
|
||||||
.set(dto)
|
.set(dto)
|
||||||
|
@ -4,10 +4,11 @@ import { jsonObjectFrom } from 'kysely/helpers/postgres';
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { Album, columns } from 'src/database';
|
import { Album, columns } from 'src/database';
|
||||||
import { DB, SharedLinks } from 'src/db';
|
|
||||||
import { DummyValue, GenerateSql } from 'src/decorators';
|
import { DummyValue, GenerateSql } from 'src/decorators';
|
||||||
import { MapAsset } from 'src/dtos/asset-response.dto';
|
import { MapAsset } from 'src/dtos/asset-response.dto';
|
||||||
import { SharedLinkType } from 'src/enum';
|
import { SharedLinkType } from 'src/enum';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
|
import { SharedLinkTable } from 'src/schema/tables/shared-link.table';
|
||||||
|
|
||||||
export type SharedLinkSearchOptions = {
|
export type SharedLinkSearchOptions = {
|
||||||
userId: string;
|
userId: string;
|
||||||
@ -183,7 +184,7 @@ export class SharedLinkRepository {
|
|||||||
.executeTakeFirst();
|
.executeTakeFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(entity: Insertable<SharedLinks> & { assetIds?: string[] }) {
|
async create(entity: Insertable<SharedLinkTable> & { assetIds?: string[] }) {
|
||||||
const { id } = await this.db
|
const { id } = await this.db
|
||||||
.insertInto('shared_links')
|
.insertInto('shared_links')
|
||||||
.values(_.omit(entity, 'assetIds'))
|
.values(_.omit(entity, 'assetIds'))
|
||||||
@ -200,7 +201,7 @@ export class SharedLinkRepository {
|
|||||||
return this.getSharedLinks(id);
|
return this.getSharedLinks(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(entity: Updateable<SharedLinks> & { id: string; assetIds?: string[] }) {
|
async update(entity: Updateable<SharedLinkTable> & { id: string; assetIds?: string[] }) {
|
||||||
const { id } = await this.db
|
const { id } = await this.db
|
||||||
.updateTable('shared_links')
|
.updateTable('shared_links')
|
||||||
.set(_.omit(entity, 'assets', 'album', 'assetIds'))
|
.set(_.omit(entity, 'assets', 'album', 'assetIds'))
|
||||||
|
@ -3,8 +3,9 @@ import { ExpressionBuilder, Kysely, Updateable } from 'kysely';
|
|||||||
import { jsonArrayFrom } from 'kysely/helpers/postgres';
|
import { jsonArrayFrom } from 'kysely/helpers/postgres';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { columns } from 'src/database';
|
import { columns } from 'src/database';
|
||||||
import { AssetStack, DB } from 'src/db';
|
|
||||||
import { DummyValue, GenerateSql } from 'src/decorators';
|
import { DummyValue, GenerateSql } from 'src/decorators';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
|
import { StackTable } from 'src/schema/tables/stack.table';
|
||||||
import { asUuid, withDefaultVisibility } from 'src/utils/database';
|
import { asUuid, withDefaultVisibility } from 'src/utils/database';
|
||||||
|
|
||||||
export interface StackSearch {
|
export interface StackSearch {
|
||||||
@ -130,7 +131,7 @@ export class StackRepository {
|
|||||||
await this.db.deleteFrom('asset_stack').where('id', 'in', ids).execute();
|
await this.db.deleteFrom('asset_stack').where('id', 'in', ids).execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
update(id: string, entity: Updateable<AssetStack>) {
|
update(id: string, entity: Updateable<StackTable>) {
|
||||||
return this.db
|
return this.db
|
||||||
.updateTable('asset_stack')
|
.updateTable('asset_stack')
|
||||||
.set(entity)
|
.set(entity)
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { Insertable, Kysely } from 'kysely';
|
import { Insertable, Kysely } from 'kysely';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { DB, SessionSyncCheckpoints } from 'src/db';
|
|
||||||
import { DummyValue, GenerateSql } from 'src/decorators';
|
import { DummyValue, GenerateSql } from 'src/decorators';
|
||||||
import { SyncEntityType } from 'src/enum';
|
import { SyncEntityType } from 'src/enum';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
|
import { SessionSyncCheckpointTable } from 'src/schema/tables/sync-checkpoint.table';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SyncCheckpointRepository {
|
export class SyncCheckpointRepository {
|
||||||
@ -18,7 +19,7 @@ export class SyncCheckpointRepository {
|
|||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
upsertAll(items: Insertable<SessionSyncCheckpoints>[]) {
|
upsertAll(items: Insertable<SessionSyncCheckpointTable>[]) {
|
||||||
return this.db
|
return this.db
|
||||||
.insertInto('session_sync_checkpoints')
|
.insertInto('session_sync_checkpoints')
|
||||||
.values(items)
|
.values(items)
|
||||||
|
@ -2,8 +2,8 @@ import { Injectable } from '@nestjs/common';
|
|||||||
import { Kysely, SelectQueryBuilder, sql } from 'kysely';
|
import { Kysely, SelectQueryBuilder, sql } from 'kysely';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { columns } from 'src/database';
|
import { columns } from 'src/database';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { DummyValue, GenerateSql } from 'src/decorators';
|
import { DummyValue, GenerateSql } from 'src/decorators';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
import { SyncAck } from 'src/types';
|
import { SyncAck } from 'src/types';
|
||||||
|
|
||||||
type AuditTables =
|
type AuditTables =
|
||||||
|
@ -2,11 +2,12 @@ import { Injectable } from '@nestjs/common';
|
|||||||
import { Insertable, Kysely } from 'kysely';
|
import { Insertable, Kysely } from 'kysely';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { readFile } from 'node:fs/promises';
|
import { readFile } from 'node:fs/promises';
|
||||||
import { DB, SystemMetadata as DbSystemMetadata } from 'src/db';
|
|
||||||
import { GenerateSql } from 'src/decorators';
|
import { GenerateSql } from 'src/decorators';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
|
import { SystemMetadataTable } from 'src/schema/tables/system-metadata.table';
|
||||||
import { SystemMetadata } from 'src/types';
|
import { SystemMetadata } from 'src/types';
|
||||||
|
|
||||||
type Upsert = Insertable<DbSystemMetadata>;
|
type Upsert = Insertable<SystemMetadataTable>;
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SystemMetadataRepository {
|
export class SystemMetadataRepository {
|
||||||
|
@ -2,9 +2,11 @@ import { Injectable } from '@nestjs/common';
|
|||||||
import { Insertable, Kysely, sql, Updateable } from 'kysely';
|
import { Insertable, Kysely, sql, Updateable } from 'kysely';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { columns } from 'src/database';
|
import { columns } from 'src/database';
|
||||||
import { DB, TagAsset, Tags } from 'src/db';
|
|
||||||
import { Chunked, ChunkedSet, DummyValue, GenerateSql } from 'src/decorators';
|
import { Chunked, ChunkedSet, DummyValue, GenerateSql } from 'src/decorators';
|
||||||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
|
import { TagAssetTable } from 'src/schema/tables/tag-asset.table';
|
||||||
|
import { TagTable } from 'src/schema/tables/tag.table';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class TagRepository {
|
export class TagRepository {
|
||||||
@ -72,12 +74,12 @@ export class TagRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GenerateSql({ params: [{ userId: DummyValue.UUID, color: DummyValue.STRING, value: DummyValue.STRING }] })
|
@GenerateSql({ params: [{ userId: DummyValue.UUID, color: DummyValue.STRING, value: DummyValue.STRING }] })
|
||||||
create(tag: Insertable<Tags>) {
|
create(tag: Insertable<TagTable>) {
|
||||||
return this.db.insertInto('tags').values(tag).returningAll().executeTakeFirstOrThrow();
|
return this.db.insertInto('tags').values(tag).returningAll().executeTakeFirstOrThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
@GenerateSql({ params: [DummyValue.UUID, { color: DummyValue.STRING }] })
|
@GenerateSql({ params: [DummyValue.UUID, { color: DummyValue.STRING }] })
|
||||||
update(id: string, dto: Updateable<Tags>) {
|
update(id: string, dto: Updateable<TagTable>) {
|
||||||
return this.db.updateTable('tags').set(dto).where('id', '=', id).returningAll().executeTakeFirstOrThrow();
|
return this.db.updateTable('tags').set(dto).where('id', '=', id).returningAll().executeTakeFirstOrThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +130,7 @@ export class TagRepository {
|
|||||||
|
|
||||||
@GenerateSql({ params: [[{ assetId: DummyValue.UUID, tagsIds: [DummyValue.UUID] }]] })
|
@GenerateSql({ params: [[{ assetId: DummyValue.UUID, tagsIds: [DummyValue.UUID] }]] })
|
||||||
@Chunked()
|
@Chunked()
|
||||||
upsertAssetIds(items: Insertable<TagAsset>[]) {
|
upsertAssetIds(items: Insertable<TagAssetTable>[]) {
|
||||||
if (items.length === 0) {
|
if (items.length === 0) {
|
||||||
return Promise.resolve([]);
|
return Promise.resolve([]);
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { Kysely } from 'kysely';
|
import { Kysely } from 'kysely';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { DummyValue, GenerateSql } from 'src/decorators';
|
import { DummyValue, GenerateSql } from 'src/decorators';
|
||||||
import { AssetStatus } from 'src/enum';
|
import { AssetStatus } from 'src/enum';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
|
|
||||||
export class TrashRepository {
|
export class TrashRepository {
|
||||||
constructor(@InjectKysely() private db: Kysely<DB>) {}
|
constructor(@InjectKysely() private db: Kysely<DB>) {}
|
||||||
|
@ -4,14 +4,15 @@ import { jsonArrayFrom } from 'kysely/helpers/postgres';
|
|||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { columns } from 'src/database';
|
import { columns } from 'src/database';
|
||||||
import { DB, UserMetadata as DbUserMetadata } from 'src/db';
|
|
||||||
import { DummyValue, GenerateSql } from 'src/decorators';
|
import { DummyValue, GenerateSql } from 'src/decorators';
|
||||||
import { AssetType, AssetVisibility, UserStatus } from 'src/enum';
|
import { AssetType, AssetVisibility, UserStatus } from 'src/enum';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
|
import { UserMetadataTable } from 'src/schema/tables/user-metadata.table';
|
||||||
import { UserTable } from 'src/schema/tables/user.table';
|
import { UserTable } from 'src/schema/tables/user.table';
|
||||||
import { UserMetadata, UserMetadataItem } from 'src/types';
|
import { UserMetadata, UserMetadataItem } from 'src/types';
|
||||||
import { asUuid } from 'src/utils/database';
|
import { asUuid } from 'src/utils/database';
|
||||||
|
|
||||||
type Upsert = Insertable<DbUserMetadata>;
|
type Upsert = Insertable<UserMetadataTable>;
|
||||||
|
|
||||||
export interface UserListFilter {
|
export interface UserListFilter {
|
||||||
id?: string;
|
id?: string;
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { Insertable, Kysely } from 'kysely';
|
import { Insertable, Kysely } from 'kysely';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { DB, VersionHistory } from 'src/db';
|
|
||||||
import { GenerateSql } from 'src/decorators';
|
import { GenerateSql } from 'src/decorators';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
|
import { VersionHistoryTable } from 'src/schema/tables/version-history.table';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class VersionHistoryRepository {
|
export class VersionHistoryRepository {
|
||||||
@ -18,7 +19,7 @@ export class VersionHistoryRepository {
|
|||||||
return this.db.selectFrom('version_history').selectAll().orderBy('createdAt', 'desc').executeTakeFirst();
|
return this.db.selectFrom('version_history').selectAll().orderBy('createdAt', 'desc').executeTakeFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
create(version: Insertable<VersionHistory>) {
|
create(version: Insertable<VersionHistoryTable>) {
|
||||||
return this.db.insertInto('version_history').values(version).returningAll().executeTakeFirstOrThrow();
|
return this.db.insertInto('version_history').values(version).returningAll().executeTakeFirstOrThrow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { Kysely } from 'kysely';
|
import { Kysely } from 'kysely';
|
||||||
import { InjectKysely } from 'nestjs-kysely';
|
import { InjectKysely } from 'nestjs-kysely';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { DummyValue, GenerateSql } from 'src/decorators';
|
import { DummyValue, GenerateSql } from 'src/decorators';
|
||||||
import { AssetVisibility } from 'src/enum';
|
import { AssetVisibility } from 'src/enum';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
import { asUuid, withExif } from 'src/utils/database';
|
import { asUuid, withExif } from 'src/utils/database';
|
||||||
|
|
||||||
export class ViewRepository {
|
export class ViewRepository {
|
||||||
|
@ -21,7 +21,7 @@ import { AlbumAuditTable } from 'src/schema/tables/album-audit.table';
|
|||||||
import { AlbumUserAuditTable } from 'src/schema/tables/album-user-audit.table';
|
import { AlbumUserAuditTable } from 'src/schema/tables/album-user-audit.table';
|
||||||
import { AlbumUserTable } from 'src/schema/tables/album-user.table';
|
import { AlbumUserTable } from 'src/schema/tables/album-user.table';
|
||||||
import { AlbumTable } from 'src/schema/tables/album.table';
|
import { AlbumTable } from 'src/schema/tables/album.table';
|
||||||
import { APIKeyTable } from 'src/schema/tables/api-key.table';
|
import { ApiKeyTable } from 'src/schema/tables/api-key.table';
|
||||||
import { AssetAuditTable } from 'src/schema/tables/asset-audit.table';
|
import { AssetAuditTable } from 'src/schema/tables/asset-audit.table';
|
||||||
import { AssetFaceTable } from 'src/schema/tables/asset-face.table';
|
import { AssetFaceTable } from 'src/schema/tables/asset-face.table';
|
||||||
import { AssetFileTable } from 'src/schema/tables/asset-files.table';
|
import { AssetFileTable } from 'src/schema/tables/asset-files.table';
|
||||||
@ -51,11 +51,12 @@ import { SessionSyncCheckpointTable } from 'src/schema/tables/sync-checkpoint.ta
|
|||||||
import { SystemMetadataTable } from 'src/schema/tables/system-metadata.table';
|
import { SystemMetadataTable } from 'src/schema/tables/system-metadata.table';
|
||||||
import { TagAssetTable } from 'src/schema/tables/tag-asset.table';
|
import { TagAssetTable } from 'src/schema/tables/tag-asset.table';
|
||||||
import { TagClosureTable } from 'src/schema/tables/tag-closure.table';
|
import { TagClosureTable } from 'src/schema/tables/tag-closure.table';
|
||||||
|
import { TagTable } from 'src/schema/tables/tag.table';
|
||||||
import { UserAuditTable } from 'src/schema/tables/user-audit.table';
|
import { UserAuditTable } from 'src/schema/tables/user-audit.table';
|
||||||
import { UserMetadataTable } from 'src/schema/tables/user-metadata.table';
|
import { UserMetadataTable } from 'src/schema/tables/user-metadata.table';
|
||||||
import { UserTable } from 'src/schema/tables/user.table';
|
import { UserTable } from 'src/schema/tables/user.table';
|
||||||
import { VersionHistoryTable } from 'src/schema/tables/version-history.table';
|
import { VersionHistoryTable } from 'src/schema/tables/version-history.table';
|
||||||
import { Database, Extensions } from 'src/sql-tools';
|
import { Database, Extensions, Generated, Int8 } from 'src/sql-tools';
|
||||||
|
|
||||||
@Extensions(['uuid-ossp', 'unaccent', 'cube', 'earthdistance', 'pg_trgm', 'plpgsql'])
|
@Extensions(['uuid-ossp', 'unaccent', 'cube', 'earthdistance', 'pg_trgm', 'plpgsql'])
|
||||||
@Database({ name: 'immich' })
|
@Database({ name: 'immich' })
|
||||||
@ -68,7 +69,7 @@ export class ImmichDatabase {
|
|||||||
AlbumUserAuditTable,
|
AlbumUserAuditTable,
|
||||||
AlbumUserTable,
|
AlbumUserTable,
|
||||||
AlbumTable,
|
AlbumTable,
|
||||||
APIKeyTable,
|
ApiKeyTable,
|
||||||
AssetAuditTable,
|
AssetAuditTable,
|
||||||
AssetFaceTable,
|
AssetFaceTable,
|
||||||
AssetJobStatusTable,
|
AssetJobStatusTable,
|
||||||
@ -96,6 +97,7 @@ export class ImmichDatabase {
|
|||||||
StackTable,
|
StackTable,
|
||||||
SessionSyncCheckpointTable,
|
SessionSyncCheckpointTable,
|
||||||
SystemMetadataTable,
|
SystemMetadataTable,
|
||||||
|
TagTable,
|
||||||
TagAssetTable,
|
TagAssetTable,
|
||||||
TagClosureTable,
|
TagClosureTable,
|
||||||
UserAuditTable,
|
UserAuditTable,
|
||||||
@ -122,3 +124,55 @@ export class ImmichDatabase {
|
|||||||
|
|
||||||
enum = [assets_status_enum, asset_face_source_type, asset_visibility_enum];
|
enum = [assets_status_enum, asset_face_source_type, asset_visibility_enum];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Migrations {
|
||||||
|
id: Generated<number>;
|
||||||
|
name: string;
|
||||||
|
timestamp: Int8;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DB {
|
||||||
|
activity: ActivityTable;
|
||||||
|
albums: AlbumTable;
|
||||||
|
albums_audit: AlbumAuditTable;
|
||||||
|
albums_assets_assets: AlbumAssetTable;
|
||||||
|
album_assets_audit: AlbumAssetAuditTable;
|
||||||
|
albums_shared_users_users: AlbumUserTable;
|
||||||
|
album_users_audit: AlbumUserAuditTable;
|
||||||
|
api_keys: ApiKeyTable;
|
||||||
|
asset_faces: AssetFaceTable;
|
||||||
|
asset_files: AssetFileTable;
|
||||||
|
asset_job_status: AssetJobStatusTable;
|
||||||
|
asset_stack: StackTable;
|
||||||
|
assets: AssetTable;
|
||||||
|
assets_audit: AssetAuditTable;
|
||||||
|
audit: AuditTable;
|
||||||
|
exif: ExifTable;
|
||||||
|
face_search: FaceSearchTable;
|
||||||
|
geodata_places: GeodataPlacesTable;
|
||||||
|
libraries: LibraryTable;
|
||||||
|
memories: MemoryTable;
|
||||||
|
memories_audit: MemoryAuditTable;
|
||||||
|
memories_assets_assets: MemoryAssetTable;
|
||||||
|
memory_assets_audit: MemoryAssetAuditTable;
|
||||||
|
migrations: Migrations;
|
||||||
|
notifications: NotificationTable;
|
||||||
|
move_history: MoveTable;
|
||||||
|
naturalearth_countries: NaturalEarthCountriesTable;
|
||||||
|
partners_audit: PartnerAuditTable;
|
||||||
|
partners: PartnerTable;
|
||||||
|
person: PersonTable;
|
||||||
|
sessions: SessionTable;
|
||||||
|
session_sync_checkpoints: SessionSyncCheckpointTable;
|
||||||
|
shared_link__asset: SharedLinkAssetTable;
|
||||||
|
shared_links: SharedLinkTable;
|
||||||
|
smart_search: SmartSearchTable;
|
||||||
|
system_metadata: SystemMetadataTable;
|
||||||
|
tag_asset: TagAssetTable;
|
||||||
|
tags: TagTable;
|
||||||
|
tags_closure: TagClosureTable;
|
||||||
|
user_metadata: UserMetadataTable;
|
||||||
|
users: UserTable;
|
||||||
|
users_audit: UserAuditTable;
|
||||||
|
version_history: VersionHistoryTable;
|
||||||
|
}
|
||||||
|
@ -7,9 +7,11 @@ import {
|
|||||||
Column,
|
Column,
|
||||||
CreateDateColumn,
|
CreateDateColumn,
|
||||||
ForeignKeyColumn,
|
ForeignKeyColumn,
|
||||||
|
Generated,
|
||||||
Index,
|
Index,
|
||||||
PrimaryGeneratedColumn,
|
PrimaryGeneratedColumn,
|
||||||
Table,
|
Table,
|
||||||
|
Timestamp,
|
||||||
UpdateDateColumn,
|
UpdateDateColumn,
|
||||||
} from 'src/sql-tools';
|
} from 'src/sql-tools';
|
||||||
|
|
||||||
@ -27,13 +29,13 @@ import {
|
|||||||
})
|
})
|
||||||
export class ActivityTable {
|
export class ActivityTable {
|
||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
id!: string;
|
id!: Generated<string>;
|
||||||
|
|
||||||
@CreateDateColumn()
|
@CreateDateColumn()
|
||||||
createdAt!: Date;
|
createdAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@UpdateDateColumn()
|
@UpdateDateColumn()
|
||||||
updatedAt!: Date;
|
updatedAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@ForeignKeyColumn(() => AlbumTable, { onDelete: 'CASCADE', onUpdate: 'CASCADE' })
|
@ForeignKeyColumn(() => AlbumTable, { onDelete: 'CASCADE', onUpdate: 'CASCADE' })
|
||||||
albumId!: string;
|
albumId!: string;
|
||||||
@ -48,8 +50,8 @@ export class ActivityTable {
|
|||||||
comment!: string | null;
|
comment!: string | null;
|
||||||
|
|
||||||
@Column({ type: 'boolean', default: false })
|
@Column({ type: 'boolean', default: false })
|
||||||
isLiked!: boolean;
|
isLiked!: Generated<boolean>;
|
||||||
|
|
||||||
@UpdateIdColumn({ indexName: 'IDX_activity_update_id' })
|
@UpdateIdColumn({ indexName: 'IDX_activity_update_id' })
|
||||||
updateId!: string;
|
updateId!: Generated<string>;
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { PrimaryGeneratedUuidV7Column } from 'src/decorators';
|
import { PrimaryGeneratedUuidV7Column } from 'src/decorators';
|
||||||
import { AlbumTable } from 'src/schema/tables/album.table';
|
import { AlbumTable } from 'src/schema/tables/album.table';
|
||||||
import { Column, CreateDateColumn, ForeignKeyColumn, Table } from 'src/sql-tools';
|
import { Column, CreateDateColumn, ForeignKeyColumn, Generated, Table, Timestamp } from 'src/sql-tools';
|
||||||
|
|
||||||
@Table('album_assets_audit')
|
@Table('album_assets_audit')
|
||||||
export class AlbumAssetAuditTable {
|
export class AlbumAssetAuditTable {
|
||||||
@PrimaryGeneratedUuidV7Column()
|
@PrimaryGeneratedUuidV7Column()
|
||||||
id!: string;
|
id!: Generated<string>;
|
||||||
|
|
||||||
@ForeignKeyColumn(() => AlbumTable, {
|
@ForeignKeyColumn(() => AlbumTable, {
|
||||||
type: 'uuid',
|
type: 'uuid',
|
||||||
@ -19,5 +19,5 @@ export class AlbumAssetAuditTable {
|
|||||||
assetId!: string;
|
assetId!: string;
|
||||||
|
|
||||||
@CreateDateColumn({ default: () => 'clock_timestamp()', indexName: 'IDX_album_assets_audit_deleted_at' })
|
@CreateDateColumn({ default: () => 'clock_timestamp()', indexName: 'IDX_album_assets_audit_deleted_at' })
|
||||||
deletedAt!: Date;
|
deletedAt!: Generated<Timestamp>;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,15 @@ import { UpdatedAtTrigger, UpdateIdColumn } from 'src/decorators';
|
|||||||
import { album_assets_delete_audit } from 'src/schema/functions';
|
import { album_assets_delete_audit } from 'src/schema/functions';
|
||||||
import { AlbumTable } from 'src/schema/tables/album.table';
|
import { AlbumTable } from 'src/schema/tables/album.table';
|
||||||
import { AssetTable } from 'src/schema/tables/asset.table';
|
import { AssetTable } from 'src/schema/tables/asset.table';
|
||||||
import { AfterDeleteTrigger, CreateDateColumn, ForeignKeyColumn, Table, UpdateDateColumn } from 'src/sql-tools';
|
import {
|
||||||
|
AfterDeleteTrigger,
|
||||||
|
CreateDateColumn,
|
||||||
|
ForeignKeyColumn,
|
||||||
|
Generated,
|
||||||
|
Table,
|
||||||
|
Timestamp,
|
||||||
|
UpdateDateColumn,
|
||||||
|
} from 'src/sql-tools';
|
||||||
|
|
||||||
@Table({ name: 'albums_assets_assets', primaryConstraintName: 'PK_c67bc36fa845fb7b18e0e398180' })
|
@Table({ name: 'albums_assets_assets', primaryConstraintName: 'PK_c67bc36fa845fb7b18e0e398180' })
|
||||||
@UpdatedAtTrigger('album_assets_updated_at')
|
@UpdatedAtTrigger('album_assets_updated_at')
|
||||||
@ -21,11 +29,11 @@ export class AlbumAssetTable {
|
|||||||
assetsId!: string;
|
assetsId!: string;
|
||||||
|
|
||||||
@CreateDateColumn()
|
@CreateDateColumn()
|
||||||
createdAt!: Date;
|
createdAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@UpdateDateColumn()
|
@UpdateDateColumn()
|
||||||
updatedAt!: Date;
|
updatedAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@UpdateIdColumn({ indexName: 'IDX_album_assets_update_id' })
|
@UpdateIdColumn({ indexName: 'IDX_album_assets_update_id' })
|
||||||
updateId!: string;
|
updateId!: Generated<string>;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { PrimaryGeneratedUuidV7Column } from 'src/decorators';
|
import { PrimaryGeneratedUuidV7Column } from 'src/decorators';
|
||||||
import { Column, CreateDateColumn, Table } from 'src/sql-tools';
|
import { Column, CreateDateColumn, Generated, Table, Timestamp } from 'src/sql-tools';
|
||||||
|
|
||||||
@Table('albums_audit')
|
@Table('albums_audit')
|
||||||
export class AlbumAuditTable {
|
export class AlbumAuditTable {
|
||||||
@PrimaryGeneratedUuidV7Column()
|
@PrimaryGeneratedUuidV7Column()
|
||||||
id!: string;
|
id!: Generated<string>;
|
||||||
|
|
||||||
@Column({ type: 'uuid', indexName: 'IDX_albums_audit_album_id' })
|
@Column({ type: 'uuid', indexName: 'IDX_albums_audit_album_id' })
|
||||||
albumId!: string;
|
albumId!: string;
|
||||||
@ -13,5 +13,5 @@ export class AlbumAuditTable {
|
|||||||
userId!: string;
|
userId!: string;
|
||||||
|
|
||||||
@CreateDateColumn({ default: () => 'clock_timestamp()', indexName: 'IDX_albums_audit_deleted_at' })
|
@CreateDateColumn({ default: () => 'clock_timestamp()', indexName: 'IDX_albums_audit_deleted_at' })
|
||||||
deletedAt!: Date;
|
deletedAt!: Generated<Timestamp>;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { PrimaryGeneratedUuidV7Column } from 'src/decorators';
|
import { PrimaryGeneratedUuidV7Column } from 'src/decorators';
|
||||||
import { Column, CreateDateColumn, Table } from 'src/sql-tools';
|
import { Column, CreateDateColumn, Generated, Table, Timestamp } from 'src/sql-tools';
|
||||||
|
|
||||||
@Table('album_users_audit')
|
@Table('album_users_audit')
|
||||||
export class AlbumUserAuditTable {
|
export class AlbumUserAuditTable {
|
||||||
@PrimaryGeneratedUuidV7Column()
|
@PrimaryGeneratedUuidV7Column()
|
||||||
id!: string;
|
id!: Generated<string>;
|
||||||
|
|
||||||
@Column({ type: 'uuid', indexName: 'IDX_album_users_audit_album_id' })
|
@Column({ type: 'uuid', indexName: 'IDX_album_users_audit_album_id' })
|
||||||
albumId!: string;
|
albumId!: string;
|
||||||
@ -13,5 +13,5 @@ export class AlbumUserAuditTable {
|
|||||||
userId!: string;
|
userId!: string;
|
||||||
|
|
||||||
@CreateDateColumn({ default: () => 'clock_timestamp()', indexName: 'IDX_album_users_audit_deleted_at' })
|
@CreateDateColumn({ default: () => 'clock_timestamp()', indexName: 'IDX_album_users_audit_deleted_at' })
|
||||||
deletedAt!: Date;
|
deletedAt!: Generated<Timestamp>;
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,10 @@ import {
|
|||||||
Column,
|
Column,
|
||||||
CreateDateColumn,
|
CreateDateColumn,
|
||||||
ForeignKeyColumn,
|
ForeignKeyColumn,
|
||||||
|
Generated,
|
||||||
Index,
|
Index,
|
||||||
Table,
|
Table,
|
||||||
|
Timestamp,
|
||||||
UpdateDateColumn,
|
UpdateDateColumn,
|
||||||
} from 'src/sql-tools';
|
} from 'src/sql-tools';
|
||||||
|
|
||||||
@ -50,17 +52,17 @@ export class AlbumUserTable {
|
|||||||
usersId!: string;
|
usersId!: string;
|
||||||
|
|
||||||
@Column({ type: 'character varying', default: AlbumUserRole.EDITOR })
|
@Column({ type: 'character varying', default: AlbumUserRole.EDITOR })
|
||||||
role!: AlbumUserRole;
|
role!: Generated<AlbumUserRole>;
|
||||||
|
|
||||||
@CreateIdColumn({ indexName: 'IDX_album_users_create_id' })
|
@CreateIdColumn({ indexName: 'IDX_album_users_create_id' })
|
||||||
createId?: string;
|
createId!: Generated<string>;
|
||||||
|
|
||||||
@CreateDateColumn()
|
@CreateDateColumn()
|
||||||
createdAt!: Date;
|
createdAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@UpdateIdColumn({ indexName: 'IDX_album_users_update_id' })
|
@UpdateIdColumn({ indexName: 'IDX_album_users_update_id' })
|
||||||
updateId?: string;
|
updateId!: Generated<string>;
|
||||||
|
|
||||||
@UpdateDateColumn()
|
@UpdateDateColumn()
|
||||||
updatedAt!: Date;
|
updatedAt!: Generated<Timestamp>;
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,10 @@ import {
|
|||||||
CreateDateColumn,
|
CreateDateColumn,
|
||||||
DeleteDateColumn,
|
DeleteDateColumn,
|
||||||
ForeignKeyColumn,
|
ForeignKeyColumn,
|
||||||
|
Generated,
|
||||||
PrimaryGeneratedColumn,
|
PrimaryGeneratedColumn,
|
||||||
Table,
|
Table,
|
||||||
|
Timestamp,
|
||||||
UpdateDateColumn,
|
UpdateDateColumn,
|
||||||
} from 'src/sql-tools';
|
} from 'src/sql-tools';
|
||||||
|
|
||||||
@ -25,16 +27,16 @@ import {
|
|||||||
})
|
})
|
||||||
export class AlbumTable {
|
export class AlbumTable {
|
||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
id!: string;
|
id!: Generated<string>;
|
||||||
|
|
||||||
@ForeignKeyColumn(() => UserTable, { onDelete: 'CASCADE', onUpdate: 'CASCADE', nullable: false })
|
@ForeignKeyColumn(() => UserTable, { onDelete: 'CASCADE', onUpdate: 'CASCADE', nullable: false })
|
||||||
ownerId!: string;
|
ownerId!: string;
|
||||||
|
|
||||||
@Column({ default: 'Untitled Album' })
|
@Column({ default: 'Untitled Album' })
|
||||||
albumName!: string;
|
albumName!: Generated<string>;
|
||||||
|
|
||||||
@CreateDateColumn()
|
@CreateDateColumn()
|
||||||
createdAt!: Date;
|
createdAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@ForeignKeyColumn(() => AssetTable, {
|
@ForeignKeyColumn(() => AssetTable, {
|
||||||
nullable: true,
|
nullable: true,
|
||||||
@ -42,23 +44,23 @@ export class AlbumTable {
|
|||||||
onUpdate: 'CASCADE',
|
onUpdate: 'CASCADE',
|
||||||
comment: 'Asset ID to be used as thumbnail',
|
comment: 'Asset ID to be used as thumbnail',
|
||||||
})
|
})
|
||||||
albumThumbnailAssetId!: string;
|
albumThumbnailAssetId!: string | null;
|
||||||
|
|
||||||
@UpdateDateColumn()
|
@UpdateDateColumn()
|
||||||
updatedAt!: Date;
|
updatedAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@Column({ type: 'text', default: '' })
|
@Column({ type: 'text', default: '' })
|
||||||
description!: string;
|
description!: Generated<string>;
|
||||||
|
|
||||||
@DeleteDateColumn()
|
@DeleteDateColumn()
|
||||||
deletedAt!: Date | null;
|
deletedAt!: Timestamp | null;
|
||||||
|
|
||||||
@Column({ type: 'boolean', default: true })
|
@Column({ type: 'boolean', default: true })
|
||||||
isActivityEnabled!: boolean;
|
isActivityEnabled!: Generated<boolean>;
|
||||||
|
|
||||||
@Column({ default: AssetOrder.DESC })
|
@Column({ default: AssetOrder.DESC })
|
||||||
order!: AssetOrder;
|
order!: Generated<AssetOrder>;
|
||||||
|
|
||||||
@UpdateIdColumn({ indexName: 'IDX_albums_update_id' })
|
@UpdateIdColumn({ indexName: 'IDX_albums_update_id' })
|
||||||
updateId?: string;
|
updateId!: Generated<string>;
|
||||||
}
|
}
|
||||||
|
@ -5,14 +5,19 @@ import {
|
|||||||
Column,
|
Column,
|
||||||
CreateDateColumn,
|
CreateDateColumn,
|
||||||
ForeignKeyColumn,
|
ForeignKeyColumn,
|
||||||
|
Generated,
|
||||||
PrimaryGeneratedColumn,
|
PrimaryGeneratedColumn,
|
||||||
Table,
|
Table,
|
||||||
|
Timestamp,
|
||||||
UpdateDateColumn,
|
UpdateDateColumn,
|
||||||
} from 'src/sql-tools';
|
} from 'src/sql-tools';
|
||||||
|
|
||||||
@Table('api_keys')
|
@Table('api_keys')
|
||||||
@UpdatedAtTrigger('api_keys_updated_at')
|
@UpdatedAtTrigger('api_keys_updated_at')
|
||||||
export class APIKeyTable {
|
export class ApiKeyTable {
|
||||||
|
@PrimaryGeneratedColumn()
|
||||||
|
id!: Generated<string>;
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
name!: string;
|
name!: string;
|
||||||
|
|
||||||
@ -23,17 +28,14 @@ export class APIKeyTable {
|
|||||||
userId!: string;
|
userId!: string;
|
||||||
|
|
||||||
@CreateDateColumn()
|
@CreateDateColumn()
|
||||||
createdAt!: Date;
|
createdAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@UpdateDateColumn()
|
@UpdateDateColumn()
|
||||||
updatedAt!: Date;
|
updatedAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@PrimaryGeneratedColumn()
|
|
||||||
id!: string;
|
|
||||||
|
|
||||||
@Column({ array: true, type: 'character varying' })
|
@Column({ array: true, type: 'character varying' })
|
||||||
permissions!: Permission[];
|
permissions!: Permission[];
|
||||||
|
|
||||||
@UpdateIdColumn({ indexName: 'IDX_api_keys_update_id' })
|
@UpdateIdColumn({ indexName: 'IDX_api_keys_update_id' })
|
||||||
updateId?: string;
|
updateId!: Generated<string>;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { PrimaryGeneratedUuidV7Column } from 'src/decorators';
|
import { PrimaryGeneratedUuidV7Column } from 'src/decorators';
|
||||||
import { Column, CreateDateColumn, Table } from 'src/sql-tools';
|
import { Column, CreateDateColumn, Generated, Table, Timestamp } from 'src/sql-tools';
|
||||||
|
|
||||||
@Table('assets_audit')
|
@Table('assets_audit')
|
||||||
export class AssetAuditTable {
|
export class AssetAuditTable {
|
||||||
@PrimaryGeneratedUuidV7Column()
|
@PrimaryGeneratedUuidV7Column()
|
||||||
id!: string;
|
id!: Generated<string>;
|
||||||
|
|
||||||
@Column({ type: 'uuid', indexName: 'IDX_assets_audit_asset_id' })
|
@Column({ type: 'uuid', indexName: 'IDX_assets_audit_asset_id' })
|
||||||
assetId!: string;
|
assetId!: string;
|
||||||
@ -13,5 +13,5 @@ export class AssetAuditTable {
|
|||||||
ownerId!: string;
|
ownerId!: string;
|
||||||
|
|
||||||
@CreateDateColumn({ default: () => 'clock_timestamp()', indexName: 'IDX_assets_audit_deleted_at' })
|
@CreateDateColumn({ default: () => 'clock_timestamp()', indexName: 'IDX_assets_audit_deleted_at' })
|
||||||
deletedAt!: Date;
|
deletedAt!: Generated<Timestamp>;
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,24 @@ import { SourceType } from 'src/enum';
|
|||||||
import { asset_face_source_type } from 'src/schema/enums';
|
import { asset_face_source_type } from 'src/schema/enums';
|
||||||
import { AssetTable } from 'src/schema/tables/asset.table';
|
import { AssetTable } from 'src/schema/tables/asset.table';
|
||||||
import { PersonTable } from 'src/schema/tables/person.table';
|
import { PersonTable } from 'src/schema/tables/person.table';
|
||||||
import { Column, DeleteDateColumn, ForeignKeyColumn, Index, PrimaryGeneratedColumn, Table } from 'src/sql-tools';
|
import {
|
||||||
|
Column,
|
||||||
|
DeleteDateColumn,
|
||||||
|
ForeignKeyColumn,
|
||||||
|
Generated,
|
||||||
|
Index,
|
||||||
|
PrimaryGeneratedColumn,
|
||||||
|
Table,
|
||||||
|
Timestamp,
|
||||||
|
} from 'src/sql-tools';
|
||||||
|
|
||||||
@Table({ name: 'asset_faces' })
|
@Table({ name: 'asset_faces' })
|
||||||
@Index({ name: 'IDX_asset_faces_assetId_personId', columns: ['assetId', 'personId'] })
|
@Index({ name: 'IDX_asset_faces_assetId_personId', columns: ['assetId', 'personId'] })
|
||||||
@Index({ columns: ['personId', 'assetId'] })
|
@Index({ columns: ['personId', 'assetId'] })
|
||||||
export class AssetFaceTable {
|
export class AssetFaceTable {
|
||||||
|
@PrimaryGeneratedColumn()
|
||||||
|
id!: Generated<string>;
|
||||||
|
|
||||||
@ForeignKeyColumn(() => AssetTable, {
|
@ForeignKeyColumn(() => AssetTable, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
onUpdate: 'CASCADE',
|
onUpdate: 'CASCADE',
|
||||||
@ -26,29 +38,26 @@ export class AssetFaceTable {
|
|||||||
personId!: string | null;
|
personId!: string | null;
|
||||||
|
|
||||||
@Column({ default: 0, type: 'integer' })
|
@Column({ default: 0, type: 'integer' })
|
||||||
imageWidth!: number;
|
imageWidth!: Generated<number>;
|
||||||
|
|
||||||
@Column({ default: 0, type: 'integer' })
|
@Column({ default: 0, type: 'integer' })
|
||||||
imageHeight!: number;
|
imageHeight!: Generated<number>;
|
||||||
|
|
||||||
@Column({ default: 0, type: 'integer' })
|
@Column({ default: 0, type: 'integer' })
|
||||||
boundingBoxX1!: number;
|
boundingBoxX1!: Generated<number>;
|
||||||
|
|
||||||
@Column({ default: 0, type: 'integer' })
|
@Column({ default: 0, type: 'integer' })
|
||||||
boundingBoxY1!: number;
|
boundingBoxY1!: Generated<number>;
|
||||||
|
|
||||||
@Column({ default: 0, type: 'integer' })
|
@Column({ default: 0, type: 'integer' })
|
||||||
boundingBoxX2!: number;
|
boundingBoxX2!: Generated<number>;
|
||||||
|
|
||||||
@Column({ default: 0, type: 'integer' })
|
@Column({ default: 0, type: 'integer' })
|
||||||
boundingBoxY2!: number;
|
boundingBoxY2!: Generated<number>;
|
||||||
|
|
||||||
@PrimaryGeneratedColumn()
|
|
||||||
id!: string;
|
|
||||||
|
|
||||||
@Column({ default: SourceType.MACHINE_LEARNING, enum: asset_face_source_type })
|
@Column({ default: SourceType.MACHINE_LEARNING, enum: asset_face_source_type })
|
||||||
sourceType!: SourceType;
|
sourceType!: Generated<SourceType>;
|
||||||
|
|
||||||
@DeleteDateColumn()
|
@DeleteDateColumn()
|
||||||
deletedAt!: Date | null;
|
deletedAt!: Timestamp | null;
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,10 @@ import {
|
|||||||
Column,
|
Column,
|
||||||
CreateDateColumn,
|
CreateDateColumn,
|
||||||
ForeignKeyColumn,
|
ForeignKeyColumn,
|
||||||
|
Generated,
|
||||||
PrimaryGeneratedColumn,
|
PrimaryGeneratedColumn,
|
||||||
Table,
|
Table,
|
||||||
|
Timestamp,
|
||||||
Unique,
|
Unique,
|
||||||
UpdateDateColumn,
|
UpdateDateColumn,
|
||||||
} from 'src/sql-tools';
|
} from 'src/sql-tools';
|
||||||
@ -16,20 +18,20 @@ import {
|
|||||||
@UpdatedAtTrigger('asset_files_updated_at')
|
@UpdatedAtTrigger('asset_files_updated_at')
|
||||||
export class AssetFileTable {
|
export class AssetFileTable {
|
||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
id!: string;
|
id!: Generated<string>;
|
||||||
|
|
||||||
@ForeignKeyColumn(() => AssetTable, {
|
@ForeignKeyColumn(() => AssetTable, {
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
onUpdate: 'CASCADE',
|
onUpdate: 'CASCADE',
|
||||||
indexName: 'IDX_asset_files_assetId',
|
indexName: 'IDX_asset_files_assetId',
|
||||||
})
|
})
|
||||||
assetId?: string;
|
assetId!: string;
|
||||||
|
|
||||||
@CreateDateColumn()
|
@CreateDateColumn()
|
||||||
createdAt!: Date;
|
createdAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@UpdateDateColumn()
|
@UpdateDateColumn()
|
||||||
updatedAt!: Date;
|
updatedAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
type!: AssetFileType;
|
type!: AssetFileType;
|
||||||
@ -38,5 +40,5 @@ export class AssetFileTable {
|
|||||||
path!: string;
|
path!: string;
|
||||||
|
|
||||||
@UpdateIdColumn({ indexName: 'IDX_asset_files_update_id' })
|
@UpdateIdColumn({ indexName: 'IDX_asset_files_update_id' })
|
||||||
updateId?: string;
|
updateId!: Generated<string>;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { AssetTable } from 'src/schema/tables/asset.table';
|
import { AssetTable } from 'src/schema/tables/asset.table';
|
||||||
import { Column, ForeignKeyColumn, Table } from 'src/sql-tools';
|
import { Column, ForeignKeyColumn, Table, Timestamp } from 'src/sql-tools';
|
||||||
|
|
||||||
@Table('asset_job_status')
|
@Table('asset_job_status')
|
||||||
export class AssetJobStatusTable {
|
export class AssetJobStatusTable {
|
||||||
@ -7,17 +7,17 @@ export class AssetJobStatusTable {
|
|||||||
assetId!: string;
|
assetId!: string;
|
||||||
|
|
||||||
@Column({ type: 'timestamp with time zone', nullable: true })
|
@Column({ type: 'timestamp with time zone', nullable: true })
|
||||||
facesRecognizedAt!: Date | null;
|
facesRecognizedAt!: Timestamp | null;
|
||||||
|
|
||||||
@Column({ type: 'timestamp with time zone', nullable: true })
|
@Column({ type: 'timestamp with time zone', nullable: true })
|
||||||
metadataExtractedAt!: Date | null;
|
metadataExtractedAt!: Timestamp | null;
|
||||||
|
|
||||||
@Column({ type: 'timestamp with time zone', nullable: true })
|
@Column({ type: 'timestamp with time zone', nullable: true })
|
||||||
duplicatesDetectedAt!: Date | null;
|
duplicatesDetectedAt!: Timestamp | null;
|
||||||
|
|
||||||
@Column({ type: 'timestamp with time zone', nullable: true })
|
@Column({ type: 'timestamp with time zone', nullable: true })
|
||||||
previewAt!: Date | null;
|
previewAt!: Timestamp | null;
|
||||||
|
|
||||||
@Column({ type: 'timestamp with time zone', nullable: true })
|
@Column({ type: 'timestamp with time zone', nullable: true })
|
||||||
thumbnailAt!: Date | null;
|
thumbnailAt!: Timestamp | null;
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,11 @@ import {
|
|||||||
CreateDateColumn,
|
CreateDateColumn,
|
||||||
DeleteDateColumn,
|
DeleteDateColumn,
|
||||||
ForeignKeyColumn,
|
ForeignKeyColumn,
|
||||||
|
Generated,
|
||||||
Index,
|
Index,
|
||||||
PrimaryGeneratedColumn,
|
PrimaryGeneratedColumn,
|
||||||
Table,
|
Table,
|
||||||
|
Timestamp,
|
||||||
UpdateDateColumn,
|
UpdateDateColumn,
|
||||||
} from 'src/sql-tools';
|
} from 'src/sql-tools';
|
||||||
import { ASSET_CHECKSUM_CONSTRAINT } from 'src/utils/database';
|
import { ASSET_CHECKSUM_CONSTRAINT } from 'src/utils/database';
|
||||||
@ -60,7 +62,7 @@ import { ASSET_CHECKSUM_CONSTRAINT } from 'src/utils/database';
|
|||||||
// For all assets, each originalpath must be unique per user and library
|
// For all assets, each originalpath must be unique per user and library
|
||||||
export class AssetTable {
|
export class AssetTable {
|
||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
id!: string;
|
id!: Generated<string>;
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
deviceAssetId!: string;
|
deviceAssetId!: string;
|
||||||
@ -78,13 +80,13 @@ export class AssetTable {
|
|||||||
originalPath!: string;
|
originalPath!: string;
|
||||||
|
|
||||||
@Column({ type: 'timestamp with time zone', indexName: 'idx_asset_file_created_at' })
|
@Column({ type: 'timestamp with time zone', indexName: 'idx_asset_file_created_at' })
|
||||||
fileCreatedAt!: Date;
|
fileCreatedAt!: Timestamp;
|
||||||
|
|
||||||
@Column({ type: 'timestamp with time zone' })
|
@Column({ type: 'timestamp with time zone' })
|
||||||
fileModifiedAt!: Date;
|
fileModifiedAt!: Timestamp;
|
||||||
|
|
||||||
@Column({ type: 'boolean', default: false })
|
@Column({ type: 'boolean', default: false })
|
||||||
isFavorite!: boolean;
|
isFavorite!: Generated<boolean>;
|
||||||
|
|
||||||
@Column({ type: 'character varying', nullable: true })
|
@Column({ type: 'character varying', nullable: true })
|
||||||
duration!: string | null;
|
duration!: string | null;
|
||||||
@ -99,10 +101,10 @@ export class AssetTable {
|
|||||||
livePhotoVideoId!: string | null;
|
livePhotoVideoId!: string | null;
|
||||||
|
|
||||||
@UpdateDateColumn()
|
@UpdateDateColumn()
|
||||||
updatedAt!: Date;
|
updatedAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@CreateDateColumn()
|
@CreateDateColumn()
|
||||||
createdAt!: Date;
|
createdAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@Column({ index: true })
|
@Column({ index: true })
|
||||||
originalFileName!: string;
|
originalFileName!: string;
|
||||||
@ -114,32 +116,32 @@ export class AssetTable {
|
|||||||
thumbhash!: Buffer | null;
|
thumbhash!: Buffer | null;
|
||||||
|
|
||||||
@Column({ type: 'boolean', default: false })
|
@Column({ type: 'boolean', default: false })
|
||||||
isOffline!: boolean;
|
isOffline!: Generated<boolean>;
|
||||||
|
|
||||||
@ForeignKeyColumn(() => LibraryTable, { onDelete: 'CASCADE', onUpdate: 'CASCADE', nullable: true })
|
@ForeignKeyColumn(() => LibraryTable, { onDelete: 'CASCADE', onUpdate: 'CASCADE', nullable: true })
|
||||||
libraryId?: string | null;
|
libraryId!: string | null;
|
||||||
|
|
||||||
@Column({ type: 'boolean', default: false })
|
@Column({ type: 'boolean', default: false })
|
||||||
isExternal!: boolean;
|
isExternal!: Generated<boolean>;
|
||||||
|
|
||||||
@DeleteDateColumn()
|
@DeleteDateColumn()
|
||||||
deletedAt!: Date | null;
|
deletedAt!: Timestamp | null;
|
||||||
|
|
||||||
@Column({ type: 'timestamp with time zone' })
|
@Column({ type: 'timestamp with time zone' })
|
||||||
localDateTime!: Date;
|
localDateTime!: Timestamp;
|
||||||
|
|
||||||
@ForeignKeyColumn(() => StackTable, { nullable: true, onDelete: 'SET NULL', onUpdate: 'CASCADE' })
|
@ForeignKeyColumn(() => StackTable, { nullable: true, onDelete: 'SET NULL', onUpdate: 'CASCADE' })
|
||||||
stackId?: string | null;
|
stackId!: string | null;
|
||||||
|
|
||||||
@Column({ type: 'uuid', nullable: true, indexName: 'IDX_assets_duplicateId' })
|
@Column({ type: 'uuid', nullable: true, indexName: 'IDX_assets_duplicateId' })
|
||||||
duplicateId!: string | null;
|
duplicateId!: string | null;
|
||||||
|
|
||||||
@Column({ enum: assets_status_enum, default: AssetStatus.ACTIVE })
|
@Column({ enum: assets_status_enum, default: AssetStatus.ACTIVE })
|
||||||
status!: AssetStatus;
|
status!: Generated<AssetStatus>;
|
||||||
|
|
||||||
@UpdateIdColumn({ indexName: 'IDX_assets_update_id' })
|
@UpdateIdColumn({ indexName: 'IDX_assets_update_id' })
|
||||||
updateId?: string;
|
updateId!: Generated<string>;
|
||||||
|
|
||||||
@Column({ enum: asset_visibility_enum, default: AssetVisibility.TIMELINE })
|
@Column({ enum: asset_visibility_enum, default: AssetVisibility.TIMELINE })
|
||||||
visibility!: AssetVisibility;
|
visibility!: Generated<AssetVisibility>;
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { DatabaseAction, EntityType } from 'src/enum';
|
import { DatabaseAction, EntityType } from 'src/enum';
|
||||||
import { Column, CreateDateColumn, Index, PrimaryColumn, Table } from 'src/sql-tools';
|
import { Column, CreateDateColumn, Generated, Index, PrimaryColumn, Table, Timestamp } from 'src/sql-tools';
|
||||||
|
|
||||||
@Table('audit')
|
@Table('audit')
|
||||||
@Index({ name: 'IDX_ownerId_createdAt', columns: ['ownerId', 'createdAt'] })
|
@Index({ name: 'IDX_ownerId_createdAt', columns: ['ownerId', 'createdAt'] })
|
||||||
export class AuditTable {
|
export class AuditTable {
|
||||||
@PrimaryColumn({ type: 'serial', synchronize: false })
|
@PrimaryColumn({ type: 'serial', synchronize: false })
|
||||||
id!: number;
|
id!: Generated<number>;
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
entityType!: EntityType;
|
entityType!: EntityType;
|
||||||
@ -20,5 +20,5 @@ export class AuditTable {
|
|||||||
ownerId!: string;
|
ownerId!: string;
|
||||||
|
|
||||||
@CreateDateColumn()
|
@CreateDateColumn()
|
||||||
createdAt!: Date;
|
createdAt!: Generated<Timestamp>;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { UpdatedAtTrigger, UpdateIdColumn } from 'src/decorators';
|
import { UpdatedAtTrigger, UpdateIdColumn } from 'src/decorators';
|
||||||
import { AssetTable } from 'src/schema/tables/asset.table';
|
import { AssetTable } from 'src/schema/tables/asset.table';
|
||||||
import { Column, ForeignKeyColumn, Table, UpdateDateColumn } from 'src/sql-tools';
|
import { Column, ForeignKeyColumn, Generated, Int8, Table, Timestamp, UpdateDateColumn } from 'src/sql-tools';
|
||||||
|
|
||||||
@Table('exif')
|
@Table('exif')
|
||||||
@UpdatedAtTrigger('asset_exif_updated_at')
|
@UpdatedAtTrigger('asset_exif_updated_at')
|
||||||
@ -21,16 +21,16 @@ export class ExifTable {
|
|||||||
exifImageHeight!: number | null;
|
exifImageHeight!: number | null;
|
||||||
|
|
||||||
@Column({ type: 'bigint', nullable: true })
|
@Column({ type: 'bigint', nullable: true })
|
||||||
fileSizeInByte!: number | null;
|
fileSizeInByte!: Int8 | null;
|
||||||
|
|
||||||
@Column({ type: 'character varying', nullable: true })
|
@Column({ type: 'character varying', nullable: true })
|
||||||
orientation!: string | null;
|
orientation!: string | null;
|
||||||
|
|
||||||
@Column({ type: 'timestamp with time zone', nullable: true })
|
@Column({ type: 'timestamp with time zone', nullable: true })
|
||||||
dateTimeOriginal!: Date | null;
|
dateTimeOriginal!: Timestamp | null;
|
||||||
|
|
||||||
@Column({ type: 'timestamp with time zone', nullable: true })
|
@Column({ type: 'timestamp with time zone', nullable: true })
|
||||||
modifyDate!: Date | null;
|
modifyDate!: Timestamp | null;
|
||||||
|
|
||||||
@Column({ type: 'character varying', nullable: true })
|
@Column({ type: 'character varying', nullable: true })
|
||||||
lensModel!: string | null;
|
lensModel!: string | null;
|
||||||
@ -60,10 +60,10 @@ export class ExifTable {
|
|||||||
country!: string | null;
|
country!: string | null;
|
||||||
|
|
||||||
@Column({ type: 'text', default: '' })
|
@Column({ type: 'text', default: '' })
|
||||||
description!: string; // or caption
|
description!: Generated<string>; // or caption
|
||||||
|
|
||||||
@Column({ type: 'double precision', nullable: true })
|
@Column({ type: 'double precision', nullable: true })
|
||||||
fps?: number | null;
|
fps!: number | null;
|
||||||
|
|
||||||
@Column({ type: 'character varying', nullable: true })
|
@Column({ type: 'character varying', nullable: true })
|
||||||
exposureTime!: string | null;
|
exposureTime!: string | null;
|
||||||
@ -93,8 +93,8 @@ export class ExifTable {
|
|||||||
rating!: number | null;
|
rating!: number | null;
|
||||||
|
|
||||||
@UpdateDateColumn({ default: () => 'clock_timestamp()' })
|
@UpdateDateColumn({ default: () => 'clock_timestamp()' })
|
||||||
updatedAt?: Date;
|
updatedAt!: Generated<Date>;
|
||||||
|
|
||||||
@UpdateIdColumn({ indexName: 'IDX_asset_exif_update_id' })
|
@UpdateIdColumn({ indexName: 'IDX_asset_exif_update_id' })
|
||||||
updateId?: string;
|
updateId!: Generated<string>;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Column, Index, PrimaryColumn, Table } from 'src/sql-tools';
|
import { Column, Index, PrimaryColumn, Table, Timestamp } from 'src/sql-tools';
|
||||||
|
|
||||||
@Table({ name: 'geodata_places', synchronize: false })
|
@Table({ name: 'geodata_places', synchronize: false })
|
||||||
@Index({
|
@Index({
|
||||||
@ -47,20 +47,20 @@ export class GeodataPlacesTable {
|
|||||||
countryCode!: string;
|
countryCode!: string;
|
||||||
|
|
||||||
@Column({ type: 'character varying', length: 20, nullable: true })
|
@Column({ type: 'character varying', length: 20, nullable: true })
|
||||||
admin1Code!: string;
|
admin1Code!: string | null;
|
||||||
|
|
||||||
@Column({ type: 'character varying', length: 80, nullable: true })
|
@Column({ type: 'character varying', length: 80, nullable: true })
|
||||||
admin2Code!: string;
|
admin2Code!: string | null;
|
||||||
|
|
||||||
@Column({ type: 'date' })
|
@Column({ type: 'date' })
|
||||||
modificationDate!: Date;
|
modificationDate!: Timestamp;
|
||||||
|
|
||||||
@Column({ type: 'character varying', nullable: true })
|
@Column({ type: 'character varying', nullable: true })
|
||||||
admin1Name!: string;
|
admin1Name!: string | null;
|
||||||
|
|
||||||
@Column({ type: 'character varying', nullable: true })
|
@Column({ type: 'character varying', nullable: true })
|
||||||
admin2Name!: string;
|
admin2Name!: string | null;
|
||||||
|
|
||||||
@Column({ type: 'character varying', nullable: true })
|
@Column({ type: 'character varying', nullable: true })
|
||||||
alternateNames!: string;
|
alternateNames!: string | null;
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,10 @@ import {
|
|||||||
CreateDateColumn,
|
CreateDateColumn,
|
||||||
DeleteDateColumn,
|
DeleteDateColumn,
|
||||||
ForeignKeyColumn,
|
ForeignKeyColumn,
|
||||||
|
Generated,
|
||||||
PrimaryGeneratedColumn,
|
PrimaryGeneratedColumn,
|
||||||
Table,
|
Table,
|
||||||
|
Timestamp,
|
||||||
UpdateDateColumn,
|
UpdateDateColumn,
|
||||||
} from 'src/sql-tools';
|
} from 'src/sql-tools';
|
||||||
|
|
||||||
@ -14,7 +16,7 @@ import {
|
|||||||
@UpdatedAtTrigger('libraries_updated_at')
|
@UpdatedAtTrigger('libraries_updated_at')
|
||||||
export class LibraryTable {
|
export class LibraryTable {
|
||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
id!: string;
|
id!: Generated<string>;
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
name!: string;
|
name!: string;
|
||||||
@ -29,17 +31,17 @@ export class LibraryTable {
|
|||||||
exclusionPatterns!: string[];
|
exclusionPatterns!: string[];
|
||||||
|
|
||||||
@CreateDateColumn()
|
@CreateDateColumn()
|
||||||
createdAt!: Date;
|
createdAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@UpdateDateColumn()
|
@UpdateDateColumn()
|
||||||
updatedAt!: Date;
|
updatedAt!: Generated<Date>;
|
||||||
|
|
||||||
@DeleteDateColumn()
|
@DeleteDateColumn()
|
||||||
deletedAt?: Date;
|
deletedAt!: Timestamp | null;
|
||||||
|
|
||||||
@Column({ type: 'timestamp with time zone', nullable: true })
|
@Column({ type: 'timestamp with time zone', nullable: true })
|
||||||
refreshedAt!: Date | null;
|
refreshedAt!: Timestamp | null;
|
||||||
|
|
||||||
@UpdateIdColumn({ indexName: 'IDX_libraries_update_id' })
|
@UpdateIdColumn({ indexName: 'IDX_libraries_update_id' })
|
||||||
updateId?: string;
|
updateId!: Generated<string>;
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
import { ColumnType } from 'kysely';
|
|
||||||
import { UpdatedAtTrigger, UpdateIdColumn } from 'src/decorators';
|
import { UpdatedAtTrigger, UpdateIdColumn } from 'src/decorators';
|
||||||
import { memory_assets_delete_audit } from 'src/schema/functions';
|
import { memory_assets_delete_audit } from 'src/schema/functions';
|
||||||
import { AssetTable } from 'src/schema/tables/asset.table';
|
import { AssetTable } from 'src/schema/tables/asset.table';
|
||||||
import { MemoryTable } from 'src/schema/tables/memory.table';
|
import { MemoryTable } from 'src/schema/tables/memory.table';
|
||||||
import { AfterDeleteTrigger, CreateDateColumn, ForeignKeyColumn, Table, UpdateDateColumn } from 'src/sql-tools';
|
import {
|
||||||
|
AfterDeleteTrigger,
|
||||||
type Timestamp = ColumnType<Date, Date | string, Date | string>;
|
CreateDateColumn,
|
||||||
type Generated<T> =
|
ForeignKeyColumn,
|
||||||
T extends ColumnType<infer S, infer I, infer U> ? ColumnType<S, I | undefined, U> : ColumnType<T, T | undefined, T>;
|
Generated,
|
||||||
|
Table,
|
||||||
|
Timestamp,
|
||||||
|
UpdateDateColumn,
|
||||||
|
} from 'src/sql-tools';
|
||||||
|
|
||||||
@Table('memories_assets_assets')
|
@Table('memories_assets_assets')
|
||||||
@UpdatedAtTrigger('memory_assets_updated_at')
|
@UpdatedAtTrigger('memory_assets_updated_at')
|
||||||
|
@ -1,10 +1,5 @@
|
|||||||
import { ColumnType } from 'kysely';
|
|
||||||
import { PrimaryGeneratedUuidV7Column } from 'src/decorators';
|
import { PrimaryGeneratedUuidV7Column } from 'src/decorators';
|
||||||
import { Column, CreateDateColumn, Table } from 'src/sql-tools';
|
import { Column, CreateDateColumn, Generated, Table, Timestamp } from 'src/sql-tools';
|
||||||
|
|
||||||
type Timestamp = ColumnType<Date, Date | string, Date | string>;
|
|
||||||
type Generated<T> =
|
|
||||||
T extends ColumnType<infer S, infer I, infer U> ? ColumnType<S, I | undefined, U> : ColumnType<T, T | undefined, T>;
|
|
||||||
|
|
||||||
@Table('memories_audit')
|
@Table('memories_audit')
|
||||||
export class MemoryAuditTable {
|
export class MemoryAuditTable {
|
||||||
@ -18,5 +13,5 @@ export class MemoryAuditTable {
|
|||||||
userId!: string;
|
userId!: string;
|
||||||
|
|
||||||
@CreateDateColumn({ default: () => 'clock_timestamp()', indexName: 'IDX_memories_audit_deleted_at' })
|
@CreateDateColumn({ default: () => 'clock_timestamp()', indexName: 'IDX_memories_audit_deleted_at' })
|
||||||
deletedAt!: Timestamp;
|
deletedAt!: Generated<Timestamp>;
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,10 @@ import {
|
|||||||
CreateDateColumn,
|
CreateDateColumn,
|
||||||
DeleteDateColumn,
|
DeleteDateColumn,
|
||||||
ForeignKeyColumn,
|
ForeignKeyColumn,
|
||||||
|
Generated,
|
||||||
PrimaryGeneratedColumn,
|
PrimaryGeneratedColumn,
|
||||||
Table,
|
Table,
|
||||||
|
Timestamp,
|
||||||
UpdateDateColumn,
|
UpdateDateColumn,
|
||||||
} from 'src/sql-tools';
|
} from 'src/sql-tools';
|
||||||
|
|
||||||
@ -24,16 +26,16 @@ import {
|
|||||||
})
|
})
|
||||||
export class MemoryTable {
|
export class MemoryTable {
|
||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
id!: string;
|
id!: Generated<string>;
|
||||||
|
|
||||||
@CreateDateColumn()
|
@CreateDateColumn()
|
||||||
createdAt!: Date;
|
createdAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@UpdateDateColumn()
|
@UpdateDateColumn()
|
||||||
updatedAt!: Date;
|
updatedAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@DeleteDateColumn()
|
@DeleteDateColumn()
|
||||||
deletedAt?: Date;
|
deletedAt!: Timestamp | null;
|
||||||
|
|
||||||
@ForeignKeyColumn(() => UserTable, { onDelete: 'CASCADE', onUpdate: 'CASCADE', nullable: false })
|
@ForeignKeyColumn(() => UserTable, { onDelete: 'CASCADE', onUpdate: 'CASCADE', nullable: false })
|
||||||
ownerId!: string;
|
ownerId!: string;
|
||||||
@ -46,22 +48,22 @@ export class MemoryTable {
|
|||||||
|
|
||||||
/** unless set to true, will be automatically deleted in the future */
|
/** unless set to true, will be automatically deleted in the future */
|
||||||
@Column({ type: 'boolean', default: false })
|
@Column({ type: 'boolean', default: false })
|
||||||
isSaved!: boolean;
|
isSaved!: Generated<boolean>;
|
||||||
|
|
||||||
/** memories are sorted in ascending order by this value */
|
/** memories are sorted in ascending order by this value */
|
||||||
@Column({ type: 'timestamp with time zone' })
|
@Column({ type: 'timestamp with time zone' })
|
||||||
memoryAt!: Date;
|
memoryAt!: Timestamp;
|
||||||
|
|
||||||
/** when the user last viewed the memory */
|
/** when the user last viewed the memory */
|
||||||
@Column({ type: 'timestamp with time zone', nullable: true })
|
@Column({ type: 'timestamp with time zone', nullable: true })
|
||||||
seenAt?: Date;
|
seenAt!: Timestamp | null;
|
||||||
|
|
||||||
@Column({ type: 'timestamp with time zone', nullable: true })
|
@Column({ type: 'timestamp with time zone', nullable: true })
|
||||||
showAt?: Date;
|
showAt!: Timestamp | null;
|
||||||
|
|
||||||
@Column({ type: 'timestamp with time zone', nullable: true })
|
@Column({ type: 'timestamp with time zone', nullable: true })
|
||||||
hideAt?: Date;
|
hideAt!: Timestamp | null;
|
||||||
|
|
||||||
@UpdateIdColumn({ indexName: 'IDX_memories_update_id' })
|
@UpdateIdColumn({ indexName: 'IDX_memories_update_id' })
|
||||||
updateId?: string;
|
updateId!: Generated<string>;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { PathType } from 'src/enum';
|
import { PathType } from 'src/enum';
|
||||||
import { Column, PrimaryGeneratedColumn, Table, Unique } from 'src/sql-tools';
|
import { Column, Generated, PrimaryGeneratedColumn, Table, Unique } from 'src/sql-tools';
|
||||||
|
|
||||||
@Table('move_history')
|
@Table('move_history')
|
||||||
// path lock (per entity)
|
// path lock (per entity)
|
||||||
@ -8,7 +8,7 @@ import { Column, PrimaryGeneratedColumn, Table, Unique } from 'src/sql-tools';
|
|||||||
@Unique({ name: 'UQ_newPath', columns: ['newPath'] })
|
@Unique({ name: 'UQ_newPath', columns: ['newPath'] })
|
||||||
export class MoveTable {
|
export class MoveTable {
|
||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
id!: string;
|
id!: Generated<string>;
|
||||||
|
|
||||||
@Column({ type: 'uuid' })
|
@Column({ type: 'uuid' })
|
||||||
entityId!: string;
|
entityId!: string;
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { Column, PrimaryGeneratedColumn, Table } from 'src/sql-tools';
|
import { Column, Generated, PrimaryGeneratedColumn, Table } from 'src/sql-tools';
|
||||||
|
|
||||||
@Table({ name: 'naturalearth_countries', primaryConstraintName: 'naturalearth_countries_pkey' })
|
@Table({ name: 'naturalearth_countries', primaryConstraintName: 'naturalearth_countries_pkey' })
|
||||||
export class NaturalEarthCountriesTable {
|
export class NaturalEarthCountriesTable {
|
||||||
@PrimaryGeneratedColumn({ strategy: 'identity' })
|
@PrimaryGeneratedColumn({ strategy: 'identity' })
|
||||||
id!: number;
|
id!: Generated<number>;
|
||||||
|
|
||||||
@Column({ type: 'character varying', length: 50 })
|
@Column({ type: 'character varying', length: 50 })
|
||||||
admin!: string;
|
admin!: string;
|
||||||
|
@ -6,8 +6,10 @@ import {
|
|||||||
CreateDateColumn,
|
CreateDateColumn,
|
||||||
DeleteDateColumn,
|
DeleteDateColumn,
|
||||||
ForeignKeyColumn,
|
ForeignKeyColumn,
|
||||||
|
Generated,
|
||||||
PrimaryGeneratedColumn,
|
PrimaryGeneratedColumn,
|
||||||
Table,
|
Table,
|
||||||
|
Timestamp,
|
||||||
UpdateDateColumn,
|
UpdateDateColumn,
|
||||||
} from 'src/sql-tools';
|
} from 'src/sql-tools';
|
||||||
|
|
||||||
@ -15,28 +17,28 @@ import {
|
|||||||
@UpdatedAtTrigger('notifications_updated_at')
|
@UpdatedAtTrigger('notifications_updated_at')
|
||||||
export class NotificationTable {
|
export class NotificationTable {
|
||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
id!: string;
|
id!: Generated<string>;
|
||||||
|
|
||||||
@CreateDateColumn()
|
@CreateDateColumn()
|
||||||
createdAt!: Date;
|
createdAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@UpdateDateColumn()
|
@UpdateDateColumn()
|
||||||
updatedAt!: Date;
|
updatedAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@DeleteDateColumn()
|
@DeleteDateColumn()
|
||||||
deletedAt?: Date;
|
deletedAt!: Timestamp | null;
|
||||||
|
|
||||||
@UpdateIdColumn({ indexName: 'IDX_notifications_update_id' })
|
@UpdateIdColumn({ indexName: 'IDX_notifications_update_id' })
|
||||||
updateId?: string;
|
updateId!: Generated<string>;
|
||||||
|
|
||||||
@ForeignKeyColumn(() => UserTable, { onDelete: 'CASCADE', onUpdate: 'CASCADE', nullable: true })
|
@ForeignKeyColumn(() => UserTable, { onDelete: 'CASCADE', onUpdate: 'CASCADE', nullable: true })
|
||||||
userId!: string;
|
userId!: string;
|
||||||
|
|
||||||
@Column({ default: NotificationLevel.Info })
|
@Column({ default: NotificationLevel.Info })
|
||||||
level!: NotificationLevel;
|
level!: Generated<NotificationLevel>;
|
||||||
|
|
||||||
@Column({ default: NotificationLevel.Info })
|
@Column({ default: NotificationLevel.Info })
|
||||||
type!: NotificationType;
|
type!: Generated<NotificationType>;
|
||||||
|
|
||||||
@Column({ type: 'jsonb', nullable: true })
|
@Column({ type: 'jsonb', nullable: true })
|
||||||
data!: any | null;
|
data!: any | null;
|
||||||
@ -45,8 +47,8 @@ export class NotificationTable {
|
|||||||
title!: string;
|
title!: string;
|
||||||
|
|
||||||
@Column({ type: 'text', nullable: true })
|
@Column({ type: 'text', nullable: true })
|
||||||
description!: string;
|
description!: string | null;
|
||||||
|
|
||||||
@Column({ type: 'timestamp with time zone', nullable: true })
|
@Column({ type: 'timestamp with time zone', nullable: true })
|
||||||
readAt?: Date | null;
|
readAt!: Timestamp | null;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { PrimaryGeneratedUuidV7Column } from 'src/decorators';
|
import { PrimaryGeneratedUuidV7Column } from 'src/decorators';
|
||||||
import { Column, CreateDateColumn, Table } from 'src/sql-tools';
|
import { Column, CreateDateColumn, Generated, Table, Timestamp } from 'src/sql-tools';
|
||||||
|
|
||||||
@Table('partners_audit')
|
@Table('partners_audit')
|
||||||
export class PartnerAuditTable {
|
export class PartnerAuditTable {
|
||||||
@PrimaryGeneratedUuidV7Column()
|
@PrimaryGeneratedUuidV7Column()
|
||||||
id!: string;
|
id!: Generated<string>;
|
||||||
|
|
||||||
@Column({ type: 'uuid', indexName: 'IDX_partners_audit_shared_by_id' })
|
@Column({ type: 'uuid', indexName: 'IDX_partners_audit_shared_by_id' })
|
||||||
sharedById!: string;
|
sharedById!: string;
|
||||||
@ -13,5 +13,5 @@ export class PartnerAuditTable {
|
|||||||
sharedWithId!: string;
|
sharedWithId!: string;
|
||||||
|
|
||||||
@CreateDateColumn({ default: () => 'clock_timestamp()', indexName: 'IDX_partners_audit_deleted_at' })
|
@CreateDateColumn({ default: () => 'clock_timestamp()', indexName: 'IDX_partners_audit_deleted_at' })
|
||||||
deletedAt!: Date;
|
deletedAt!: Generated<Timestamp>;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,16 @@
|
|||||||
import { CreateIdColumn, UpdatedAtTrigger, UpdateIdColumn } from 'src/decorators';
|
import { CreateIdColumn, UpdatedAtTrigger, UpdateIdColumn } from 'src/decorators';
|
||||||
import { partners_delete_audit } from 'src/schema/functions';
|
import { partners_delete_audit } from 'src/schema/functions';
|
||||||
import { UserTable } from 'src/schema/tables/user.table';
|
import { UserTable } from 'src/schema/tables/user.table';
|
||||||
import { AfterDeleteTrigger, Column, CreateDateColumn, ForeignKeyColumn, Table, UpdateDateColumn } from 'src/sql-tools';
|
import {
|
||||||
|
AfterDeleteTrigger,
|
||||||
|
Column,
|
||||||
|
CreateDateColumn,
|
||||||
|
ForeignKeyColumn,
|
||||||
|
Generated,
|
||||||
|
Table,
|
||||||
|
Timestamp,
|
||||||
|
UpdateDateColumn,
|
||||||
|
} from 'src/sql-tools';
|
||||||
|
|
||||||
@Table('partners')
|
@Table('partners')
|
||||||
@UpdatedAtTrigger('partners_updated_at')
|
@UpdatedAtTrigger('partners_updated_at')
|
||||||
@ -25,17 +34,17 @@ export class PartnerTable {
|
|||||||
sharedWithId!: string;
|
sharedWithId!: string;
|
||||||
|
|
||||||
@CreateDateColumn()
|
@CreateDateColumn()
|
||||||
createdAt!: Date;
|
createdAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@CreateIdColumn({ indexName: 'IDX_partners_create_id' })
|
@CreateIdColumn({ indexName: 'IDX_partners_create_id' })
|
||||||
createId!: string;
|
createId!: Generated<string>;
|
||||||
|
|
||||||
@UpdateDateColumn()
|
@UpdateDateColumn()
|
||||||
updatedAt!: Date;
|
updatedAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@Column({ type: 'boolean', default: false })
|
@Column({ type: 'boolean', default: false })
|
||||||
inTimeline!: boolean;
|
inTimeline!: Generated<boolean>;
|
||||||
|
|
||||||
@UpdateIdColumn({ indexName: 'IDX_partners_update_id' })
|
@UpdateIdColumn({ indexName: 'IDX_partners_update_id' })
|
||||||
updateId!: string;
|
updateId!: Generated<string>;
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,10 @@ import {
|
|||||||
Column,
|
Column,
|
||||||
CreateDateColumn,
|
CreateDateColumn,
|
||||||
ForeignKeyColumn,
|
ForeignKeyColumn,
|
||||||
|
Generated,
|
||||||
PrimaryGeneratedColumn,
|
PrimaryGeneratedColumn,
|
||||||
Table,
|
Table,
|
||||||
|
Timestamp,
|
||||||
UpdateDateColumn,
|
UpdateDateColumn,
|
||||||
} from 'src/sql-tools';
|
} from 'src/sql-tools';
|
||||||
|
|
||||||
@ -16,38 +18,38 @@ import {
|
|||||||
@Check({ name: 'CHK_b0f82b0ed662bfc24fbb58bb45', expression: `"birthDate" <= CURRENT_DATE` })
|
@Check({ name: 'CHK_b0f82b0ed662bfc24fbb58bb45', expression: `"birthDate" <= CURRENT_DATE` })
|
||||||
export class PersonTable {
|
export class PersonTable {
|
||||||
@PrimaryGeneratedColumn('uuid')
|
@PrimaryGeneratedColumn('uuid')
|
||||||
id!: string;
|
id!: Generated<string>;
|
||||||
|
|
||||||
@CreateDateColumn()
|
@CreateDateColumn()
|
||||||
createdAt!: Date;
|
createdAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@UpdateDateColumn()
|
@UpdateDateColumn()
|
||||||
updatedAt!: Date;
|
updatedAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@ForeignKeyColumn(() => UserTable, { onDelete: 'CASCADE', onUpdate: 'CASCADE', nullable: false })
|
@ForeignKeyColumn(() => UserTable, { onDelete: 'CASCADE', onUpdate: 'CASCADE', nullable: false })
|
||||||
ownerId!: string;
|
ownerId!: string;
|
||||||
|
|
||||||
@Column({ default: '' })
|
@Column({ default: '' })
|
||||||
name!: string;
|
name!: Generated<string>;
|
||||||
|
|
||||||
@Column({ default: '' })
|
@Column({ default: '' })
|
||||||
thumbnailPath!: string;
|
thumbnailPath!: Generated<string>;
|
||||||
|
|
||||||
@Column({ type: 'boolean', default: false })
|
@Column({ type: 'boolean', default: false })
|
||||||
isHidden!: boolean;
|
isHidden!: Generated<boolean>;
|
||||||
|
|
||||||
@Column({ type: 'date', nullable: true })
|
@Column({ type: 'date', nullable: true })
|
||||||
birthDate!: Date | string | null;
|
birthDate!: Timestamp | null;
|
||||||
|
|
||||||
@ForeignKeyColumn(() => AssetFaceTable, { onDelete: 'SET NULL', nullable: true })
|
@ForeignKeyColumn(() => AssetFaceTable, { onDelete: 'SET NULL', nullable: true })
|
||||||
faceAssetId!: string | null;
|
faceAssetId!: string | null;
|
||||||
|
|
||||||
@Column({ type: 'boolean', default: false })
|
@Column({ type: 'boolean', default: false })
|
||||||
isFavorite!: boolean;
|
isFavorite!: Generated<boolean>;
|
||||||
|
|
||||||
@Column({ type: 'character varying', nullable: true, default: null })
|
@Column({ type: 'character varying', nullable: true, default: null })
|
||||||
color?: string | null;
|
color!: string | null;
|
||||||
|
|
||||||
@UpdateIdColumn({ indexName: 'IDX_person_update_id' })
|
@UpdateIdColumn({ indexName: 'IDX_person_update_id' })
|
||||||
updateId!: string;
|
updateId!: Generated<string>;
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,10 @@ import {
|
|||||||
Column,
|
Column,
|
||||||
CreateDateColumn,
|
CreateDateColumn,
|
||||||
ForeignKeyColumn,
|
ForeignKeyColumn,
|
||||||
|
Generated,
|
||||||
PrimaryGeneratedColumn,
|
PrimaryGeneratedColumn,
|
||||||
Table,
|
Table,
|
||||||
|
Timestamp,
|
||||||
UpdateDateColumn,
|
UpdateDateColumn,
|
||||||
} from 'src/sql-tools';
|
} from 'src/sql-tools';
|
||||||
|
|
||||||
@ -13,20 +15,20 @@ import {
|
|||||||
@UpdatedAtTrigger('sessions_updated_at')
|
@UpdatedAtTrigger('sessions_updated_at')
|
||||||
export class SessionTable {
|
export class SessionTable {
|
||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
id!: string;
|
id!: Generated<string>;
|
||||||
|
|
||||||
// TODO convert to byte[]
|
// TODO convert to byte[]
|
||||||
@Column()
|
@Column()
|
||||||
token!: string;
|
token!: string;
|
||||||
|
|
||||||
@CreateDateColumn()
|
@CreateDateColumn()
|
||||||
createdAt!: Date;
|
createdAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@UpdateDateColumn()
|
@UpdateDateColumn()
|
||||||
updatedAt!: Date;
|
updatedAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@Column({ type: 'timestamp with time zone', nullable: true })
|
@Column({ type: 'timestamp with time zone', nullable: true })
|
||||||
expiresAt!: Date | null;
|
expiresAt!: Timestamp | null;
|
||||||
|
|
||||||
@ForeignKeyColumn(() => UserTable, { onUpdate: 'CASCADE', onDelete: 'CASCADE' })
|
@ForeignKeyColumn(() => UserTable, { onUpdate: 'CASCADE', onDelete: 'CASCADE' })
|
||||||
userId!: string;
|
userId!: string;
|
||||||
@ -35,14 +37,14 @@ export class SessionTable {
|
|||||||
parentId!: string | null;
|
parentId!: string | null;
|
||||||
|
|
||||||
@Column({ default: '' })
|
@Column({ default: '' })
|
||||||
deviceType!: string;
|
deviceType!: Generated<string>;
|
||||||
|
|
||||||
@Column({ default: '' })
|
@Column({ default: '' })
|
||||||
deviceOS!: string;
|
deviceOS!: Generated<string>;
|
||||||
|
|
||||||
@UpdateIdColumn({ indexName: 'IDX_sessions_update_id' })
|
@UpdateIdColumn({ indexName: 'IDX_sessions_update_id' })
|
||||||
updateId!: string;
|
updateId!: Generated<string>;
|
||||||
|
|
||||||
@Column({ type: 'timestamp with time zone', nullable: true })
|
@Column({ type: 'timestamp with time zone', nullable: true })
|
||||||
pinExpiresAt!: Date | null;
|
pinExpiresAt!: Timestamp | null;
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,22 @@
|
|||||||
import { SharedLinkType } from 'src/enum';
|
import { SharedLinkType } from 'src/enum';
|
||||||
import { AlbumTable } from 'src/schema/tables/album.table';
|
import { AlbumTable } from 'src/schema/tables/album.table';
|
||||||
import { UserTable } from 'src/schema/tables/user.table';
|
import { UserTable } from 'src/schema/tables/user.table';
|
||||||
import { Column, CreateDateColumn, ForeignKeyColumn, PrimaryGeneratedColumn, Table, Unique } from 'src/sql-tools';
|
import {
|
||||||
|
Column,
|
||||||
|
CreateDateColumn,
|
||||||
|
ForeignKeyColumn,
|
||||||
|
Generated,
|
||||||
|
PrimaryGeneratedColumn,
|
||||||
|
Table,
|
||||||
|
Timestamp,
|
||||||
|
Unique,
|
||||||
|
} from 'src/sql-tools';
|
||||||
|
|
||||||
@Table('shared_links')
|
@Table('shared_links')
|
||||||
@Unique({ name: 'UQ_sharedlink_key', columns: ['key'] })
|
@Unique({ name: 'UQ_sharedlink_key', columns: ['key'] })
|
||||||
export class SharedLinkTable {
|
export class SharedLinkTable {
|
||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
id!: string;
|
id!: Generated<string>;
|
||||||
|
|
||||||
@Column({ type: 'character varying', nullable: true })
|
@Column({ type: 'character varying', nullable: true })
|
||||||
description!: string | null;
|
description!: string | null;
|
||||||
@ -22,10 +31,10 @@ export class SharedLinkTable {
|
|||||||
type!: SharedLinkType;
|
type!: SharedLinkType;
|
||||||
|
|
||||||
@CreateDateColumn()
|
@CreateDateColumn()
|
||||||
createdAt!: Date;
|
createdAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@Column({ type: 'timestamp with time zone', nullable: true })
|
@Column({ type: 'timestamp with time zone', nullable: true })
|
||||||
expiresAt!: Date | null;
|
expiresAt!: Timestamp | null;
|
||||||
|
|
||||||
@Column({ type: 'boolean', default: false })
|
@Column({ type: 'boolean', default: false })
|
||||||
allowUpload!: boolean;
|
allowUpload!: boolean;
|
||||||
@ -36,13 +45,13 @@ export class SharedLinkTable {
|
|||||||
onUpdate: 'CASCADE',
|
onUpdate: 'CASCADE',
|
||||||
indexName: 'IDX_sharedlink_albumId',
|
indexName: 'IDX_sharedlink_albumId',
|
||||||
})
|
})
|
||||||
albumId!: string;
|
albumId!: string | null;
|
||||||
|
|
||||||
@Column({ type: 'boolean', default: true })
|
@Column({ type: 'boolean', default: true })
|
||||||
allowDownload!: boolean;
|
allowDownload!: Generated<boolean>;
|
||||||
|
|
||||||
@Column({ type: 'boolean', default: true })
|
@Column({ type: 'boolean', default: true })
|
||||||
showExif!: boolean;
|
showExif!: Generated<boolean>;
|
||||||
|
|
||||||
@Column({ type: 'character varying', nullable: true })
|
@Column({ type: 'character varying', nullable: true })
|
||||||
password!: string | null;
|
password!: string | null;
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { AssetTable } from 'src/schema/tables/asset.table';
|
import { AssetTable } from 'src/schema/tables/asset.table';
|
||||||
import { UserTable } from 'src/schema/tables/user.table';
|
import { UserTable } from 'src/schema/tables/user.table';
|
||||||
import { ForeignKeyColumn, PrimaryGeneratedColumn, Table } from 'src/sql-tools';
|
import { ForeignKeyColumn, Generated, PrimaryGeneratedColumn, Table } from 'src/sql-tools';
|
||||||
|
|
||||||
@Table('asset_stack')
|
@Table('asset_stack')
|
||||||
export class StackTable {
|
export class StackTable {
|
||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
id!: string;
|
id!: Generated<string>;
|
||||||
|
|
||||||
//TODO: Add constraint to ensure primary asset exists in the assets array
|
//TODO: Add constraint to ensure primary asset exists in the assets array
|
||||||
@ForeignKeyColumn(() => AssetTable, { nullable: false, unique: true })
|
@ForeignKeyColumn(() => AssetTable, { nullable: false, unique: true })
|
||||||
|
@ -1,7 +1,16 @@
|
|||||||
import { UpdatedAtTrigger, UpdateIdColumn } from 'src/decorators';
|
import { UpdatedAtTrigger, UpdateIdColumn } from 'src/decorators';
|
||||||
import { SyncEntityType } from 'src/enum';
|
import { SyncEntityType } from 'src/enum';
|
||||||
import { SessionTable } from 'src/schema/tables/session.table';
|
import { SessionTable } from 'src/schema/tables/session.table';
|
||||||
import { Column, CreateDateColumn, ForeignKeyColumn, PrimaryColumn, Table, UpdateDateColumn } from 'src/sql-tools';
|
import {
|
||||||
|
Column,
|
||||||
|
CreateDateColumn,
|
||||||
|
ForeignKeyColumn,
|
||||||
|
Generated,
|
||||||
|
PrimaryColumn,
|
||||||
|
Table,
|
||||||
|
Timestamp,
|
||||||
|
UpdateDateColumn,
|
||||||
|
} from 'src/sql-tools';
|
||||||
|
|
||||||
@Table('session_sync_checkpoints')
|
@Table('session_sync_checkpoints')
|
||||||
@UpdatedAtTrigger('session_sync_checkpoints_updated_at')
|
@UpdatedAtTrigger('session_sync_checkpoints_updated_at')
|
||||||
@ -13,14 +22,14 @@ export class SessionSyncCheckpointTable {
|
|||||||
type!: SyncEntityType;
|
type!: SyncEntityType;
|
||||||
|
|
||||||
@CreateDateColumn()
|
@CreateDateColumn()
|
||||||
createdAt!: Date;
|
createdAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@UpdateDateColumn()
|
@UpdateDateColumn()
|
||||||
updatedAt!: Date;
|
updatedAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
ack!: string;
|
ack!: string;
|
||||||
|
|
||||||
@UpdateIdColumn({ indexName: 'IDX_session_sync_checkpoints_update_id' })
|
@UpdateIdColumn({ indexName: 'IDX_session_sync_checkpoints_update_id' })
|
||||||
updateId!: string;
|
updateId!: Generated<string>;
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,10 @@ import {
|
|||||||
Column,
|
Column,
|
||||||
CreateDateColumn,
|
CreateDateColumn,
|
||||||
ForeignKeyColumn,
|
ForeignKeyColumn,
|
||||||
|
Generated,
|
||||||
PrimaryGeneratedColumn,
|
PrimaryGeneratedColumn,
|
||||||
Table,
|
Table,
|
||||||
|
Timestamp,
|
||||||
Unique,
|
Unique,
|
||||||
UpdateDateColumn,
|
UpdateDateColumn,
|
||||||
} from 'src/sql-tools';
|
} from 'src/sql-tools';
|
||||||
@ -15,7 +17,7 @@ import {
|
|||||||
@Unique({ columns: ['userId', 'value'] })
|
@Unique({ columns: ['userId', 'value'] })
|
||||||
export class TagTable {
|
export class TagTable {
|
||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
id!: string;
|
id!: Generated<string>;
|
||||||
|
|
||||||
@ForeignKeyColumn(() => UserTable, {
|
@ForeignKeyColumn(() => UserTable, {
|
||||||
onUpdate: 'CASCADE',
|
onUpdate: 'CASCADE',
|
||||||
@ -29,17 +31,17 @@ export class TagTable {
|
|||||||
value!: string;
|
value!: string;
|
||||||
|
|
||||||
@CreateDateColumn()
|
@CreateDateColumn()
|
||||||
createdAt!: Date;
|
createdAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@UpdateDateColumn()
|
@UpdateDateColumn()
|
||||||
updatedAt!: Date;
|
updatedAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@Column({ type: 'character varying', nullable: true, default: null })
|
@Column({ type: 'character varying', nullable: true, default: null })
|
||||||
color!: string | null;
|
color!: string | null;
|
||||||
|
|
||||||
@ForeignKeyColumn(() => TagTable, { nullable: true, onDelete: 'CASCADE' })
|
@ForeignKeyColumn(() => TagTable, { nullable: true, onDelete: 'CASCADE' })
|
||||||
parentId?: string;
|
parentId!: string | null;
|
||||||
|
|
||||||
@UpdateIdColumn({ indexName: 'IDX_tags_update_id' })
|
@UpdateIdColumn({ indexName: 'IDX_tags_update_id' })
|
||||||
updateId!: string;
|
updateId!: Generated<string>;
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
import { PrimaryGeneratedUuidV7Column } from 'src/decorators';
|
import { PrimaryGeneratedUuidV7Column } from 'src/decorators';
|
||||||
import { Column, CreateDateColumn, Table } from 'src/sql-tools';
|
import { Column, CreateDateColumn, Generated, Table, Timestamp } from 'src/sql-tools';
|
||||||
|
|
||||||
@Table('users_audit')
|
@Table('users_audit')
|
||||||
export class UserAuditTable {
|
export class UserAuditTable {
|
||||||
|
@PrimaryGeneratedUuidV7Column()
|
||||||
|
id!: Generated<string>;
|
||||||
|
|
||||||
@Column({ type: 'uuid' })
|
@Column({ type: 'uuid' })
|
||||||
userId!: string;
|
userId!: string;
|
||||||
|
|
||||||
@CreateDateColumn({ default: () => 'clock_timestamp()', indexName: 'IDX_users_audit_deleted_at' })
|
@CreateDateColumn({ default: () => 'clock_timestamp()', indexName: 'IDX_users_audit_deleted_at' })
|
||||||
deletedAt!: Date;
|
deletedAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@PrimaryGeneratedUuidV7Column()
|
|
||||||
id!: string;
|
|
||||||
}
|
}
|
||||||
|
@ -7,16 +7,14 @@ import {
|
|||||||
Column,
|
Column,
|
||||||
CreateDateColumn,
|
CreateDateColumn,
|
||||||
DeleteDateColumn,
|
DeleteDateColumn,
|
||||||
|
Generated,
|
||||||
Index,
|
Index,
|
||||||
PrimaryGeneratedColumn,
|
PrimaryGeneratedColumn,
|
||||||
Table,
|
Table,
|
||||||
|
Timestamp,
|
||||||
UpdateDateColumn,
|
UpdateDateColumn,
|
||||||
} from 'src/sql-tools';
|
} from 'src/sql-tools';
|
||||||
|
|
||||||
type Timestamp = ColumnType<Date, Date | string, Date | string>;
|
|
||||||
type Generated<T> =
|
|
||||||
T extends ColumnType<infer S, infer I, infer U> ? ColumnType<S, I | undefined, U> : ColumnType<T, T | undefined, T>;
|
|
||||||
|
|
||||||
@Table('users')
|
@Table('users')
|
||||||
@UpdatedAtTrigger('users_updated_at')
|
@UpdatedAtTrigger('users_updated_at')
|
||||||
@AfterDeleteTrigger({
|
@AfterDeleteTrigger({
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { Column, CreateDateColumn, PrimaryGeneratedColumn, Table } from 'src/sql-tools';
|
import { Column, CreateDateColumn, Generated, PrimaryGeneratedColumn, Table, Timestamp } from 'src/sql-tools';
|
||||||
|
|
||||||
@Table('version_history')
|
@Table('version_history')
|
||||||
export class VersionHistoryTable {
|
export class VersionHistoryTable {
|
||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
id!: string;
|
id!: Generated<string>;
|
||||||
|
|
||||||
@CreateDateColumn()
|
@CreateDateColumn()
|
||||||
createdAt!: Date;
|
createdAt!: Generated<Timestamp>;
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
version!: string;
|
version!: string;
|
||||||
|
@ -6,7 +6,6 @@ import path, { basename, isAbsolute, parse } from 'node:path';
|
|||||||
import picomatch from 'picomatch';
|
import picomatch from 'picomatch';
|
||||||
import { JOBS_LIBRARY_PAGINATION_SIZE } from 'src/constants';
|
import { JOBS_LIBRARY_PAGINATION_SIZE } from 'src/constants';
|
||||||
import { StorageCore } from 'src/cores/storage.core';
|
import { StorageCore } from 'src/cores/storage.core';
|
||||||
import { Assets } from 'src/db';
|
|
||||||
import { OnEvent, OnJob } from 'src/decorators';
|
import { OnEvent, OnJob } from 'src/decorators';
|
||||||
import {
|
import {
|
||||||
CreateLibraryDto,
|
CreateLibraryDto,
|
||||||
@ -21,6 +20,7 @@ import {
|
|||||||
import { AssetStatus, AssetType, DatabaseLock, ImmichWorker, JobName, JobStatus, QueueName } from 'src/enum';
|
import { AssetStatus, AssetType, DatabaseLock, ImmichWorker, JobName, JobStatus, QueueName } from 'src/enum';
|
||||||
import { ArgOf } from 'src/repositories/event.repository';
|
import { ArgOf } from 'src/repositories/event.repository';
|
||||||
import { AssetSyncResult } from 'src/repositories/library.repository';
|
import { AssetSyncResult } from 'src/repositories/library.repository';
|
||||||
|
import { AssetTable } from 'src/schema/tables/asset.table';
|
||||||
import { BaseService } from 'src/services/base.service';
|
import { BaseService } from 'src/services/base.service';
|
||||||
import { JobOf } from 'src/types';
|
import { JobOf } from 'src/types';
|
||||||
import { mimeTypes } from 'src/utils/mime-types';
|
import { mimeTypes } from 'src/utils/mime-types';
|
||||||
@ -237,7 +237,7 @@ export class LibraryService extends BaseService {
|
|||||||
return JobStatus.FAILED;
|
return JobStatus.FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
const assetImports: Insertable<Assets>[] = [];
|
const assetImports: Insertable<AssetTable>[] = [];
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
job.paths.map((path) =>
|
job.paths.map((path) =>
|
||||||
this.processEntity(path, library.ownerId, job.libraryId)
|
this.processEntity(path, library.ownerId, job.libraryId)
|
||||||
|
@ -9,7 +9,6 @@ import path from 'node:path';
|
|||||||
import { JOBS_ASSET_PAGINATION_SIZE } from 'src/constants';
|
import { JOBS_ASSET_PAGINATION_SIZE } from 'src/constants';
|
||||||
import { StorageCore } from 'src/cores/storage.core';
|
import { StorageCore } from 'src/cores/storage.core';
|
||||||
import { Asset, AssetFace } from 'src/database';
|
import { Asset, AssetFace } from 'src/database';
|
||||||
import { AssetFaces, Exif, Person } from 'src/db';
|
|
||||||
import { OnEvent, OnJob } from 'src/decorators';
|
import { OnEvent, OnJob } from 'src/decorators';
|
||||||
import {
|
import {
|
||||||
AssetType,
|
AssetType,
|
||||||
@ -25,6 +24,9 @@ import {
|
|||||||
import { ArgOf } from 'src/repositories/event.repository';
|
import { ArgOf } from 'src/repositories/event.repository';
|
||||||
import { ReverseGeocodeResult } from 'src/repositories/map.repository';
|
import { ReverseGeocodeResult } from 'src/repositories/map.repository';
|
||||||
import { ImmichTags } from 'src/repositories/metadata.repository';
|
import { ImmichTags } from 'src/repositories/metadata.repository';
|
||||||
|
import { AssetFaceTable } from 'src/schema/tables/asset-face.table';
|
||||||
|
import { ExifTable } from 'src/schema/tables/exif.table';
|
||||||
|
import { PersonTable } from 'src/schema/tables/person.table';
|
||||||
import { BaseService } from 'src/services/base.service';
|
import { BaseService } from 'src/services/base.service';
|
||||||
import { JobItem, JobOf } from 'src/types';
|
import { JobItem, JobOf } from 'src/types';
|
||||||
import { isFaceImportEnabled } from 'src/utils/misc';
|
import { isFaceImportEnabled } from 'src/utils/misc';
|
||||||
@ -162,7 +164,7 @@ export class MetadataService extends BaseService {
|
|||||||
|
|
||||||
private async linkLivePhotos(
|
private async linkLivePhotos(
|
||||||
asset: { id: string; type: AssetType; ownerId: string; libraryId: string | null },
|
asset: { id: string; type: AssetType; ownerId: string; libraryId: string | null },
|
||||||
exifInfo: Insertable<Exif>,
|
exifInfo: Insertable<ExifTable>,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (!exifInfo.livePhotoCID) {
|
if (!exifInfo.livePhotoCID) {
|
||||||
return;
|
return;
|
||||||
@ -240,7 +242,7 @@ export class MetadataService extends BaseService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const exifData: Insertable<Exif> = {
|
const exifData: Insertable<ExifTable> = {
|
||||||
assetId: asset.id,
|
assetId: asset.id,
|
||||||
|
|
||||||
// dates
|
// dates
|
||||||
@ -710,10 +712,10 @@ export class MetadataService extends BaseService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const facesToAdd: (Insertable<AssetFaces> & { assetId: string })[] = [];
|
const facesToAdd: (Insertable<AssetFaceTable> & { assetId: string })[] = [];
|
||||||
const existingNames = await this.personRepository.getDistinctNames(asset.ownerId, { withHidden: true });
|
const existingNames = await this.personRepository.getDistinctNames(asset.ownerId, { withHidden: true });
|
||||||
const existingNameMap = new Map(existingNames.map(({ id, name }) => [name.toLowerCase(), id]));
|
const existingNameMap = new Map(existingNames.map(({ id, name }) => [name.toLowerCase(), id]));
|
||||||
const missing: (Insertable<Person> & { ownerId: string })[] = [];
|
const missing: (Insertable<PersonTable> & { ownerId: string })[] = [];
|
||||||
const missingWithFaceAsset: { id: string; ownerId: string; faceAssetId: string }[] = [];
|
const missingWithFaceAsset: { id: string; ownerId: string; faceAssetId: string }[] = [];
|
||||||
|
|
||||||
const adjustedRegionInfo = this.orientRegionInfo(tags.RegionInfo, tags.Orientation);
|
const adjustedRegionInfo = this.orientRegionInfo(tags.RegionInfo, tags.Orientation);
|
||||||
|
@ -2,7 +2,6 @@ import { BadRequestException, Injectable, NotFoundException } from '@nestjs/comm
|
|||||||
import { Insertable, Updateable } from 'kysely';
|
import { Insertable, Updateable } from 'kysely';
|
||||||
import { JOBS_ASSET_PAGINATION_SIZE } from 'src/constants';
|
import { JOBS_ASSET_PAGINATION_SIZE } from 'src/constants';
|
||||||
import { Person } from 'src/database';
|
import { Person } from 'src/database';
|
||||||
import { AssetFaces, FaceSearch } from 'src/db';
|
|
||||||
import { Chunked, OnJob } from 'src/decorators';
|
import { Chunked, OnJob } from 'src/decorators';
|
||||||
import { BulkIdErrorReason, BulkIdResponseDto, BulkIdsDto } from 'src/dtos/asset-ids.response.dto';
|
import { BulkIdErrorReason, BulkIdResponseDto, BulkIdsDto } from 'src/dtos/asset-ids.response.dto';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
@ -37,6 +36,8 @@ import {
|
|||||||
} from 'src/enum';
|
} from 'src/enum';
|
||||||
import { BoundingBox } from 'src/repositories/machine-learning.repository';
|
import { BoundingBox } from 'src/repositories/machine-learning.repository';
|
||||||
import { UpdateFacesData } from 'src/repositories/person.repository';
|
import { UpdateFacesData } from 'src/repositories/person.repository';
|
||||||
|
import { AssetFaceTable } from 'src/schema/tables/asset-face.table';
|
||||||
|
import { FaceSearchTable } from 'src/schema/tables/face-search.table';
|
||||||
import { BaseService } from 'src/services/base.service';
|
import { BaseService } from 'src/services/base.service';
|
||||||
import { JobItem, JobOf } from 'src/types';
|
import { JobItem, JobOf } from 'src/types';
|
||||||
import { ImmichFileResponse } from 'src/utils/file';
|
import { ImmichFileResponse } from 'src/utils/file';
|
||||||
@ -317,8 +318,8 @@ export class PersonService extends BaseService {
|
|||||||
);
|
);
|
||||||
this.logger.debug(`${faces.length} faces detected in ${previewFile.path}`);
|
this.logger.debug(`${faces.length} faces detected in ${previewFile.path}`);
|
||||||
|
|
||||||
const facesToAdd: (Insertable<AssetFaces> & { id: string })[] = [];
|
const facesToAdd: (Insertable<AssetFaceTable> & { id: string })[] = [];
|
||||||
const embeddings: FaceSearch[] = [];
|
const embeddings: FaceSearchTable[] = [];
|
||||||
const mlFaceIds = new Set<string>();
|
const mlFaceIds = new Set<string>();
|
||||||
|
|
||||||
for (const face of asset.faces) {
|
for (const face of asset.faces) {
|
||||||
|
@ -3,7 +3,6 @@ import { Insertable } from 'kysely';
|
|||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import { Writable } from 'node:stream';
|
import { Writable } from 'node:stream';
|
||||||
import { AUDIT_LOG_MAX_DURATION } from 'src/constants';
|
import { AUDIT_LOG_MAX_DURATION } from 'src/constants';
|
||||||
import { SessionSyncCheckpoints } from 'src/db';
|
|
||||||
import { AssetResponseDto, mapAsset } from 'src/dtos/asset-response.dto';
|
import { AssetResponseDto, mapAsset } from 'src/dtos/asset-response.dto';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
import {
|
import {
|
||||||
@ -17,6 +16,7 @@ import {
|
|||||||
SyncStreamDto,
|
SyncStreamDto,
|
||||||
} from 'src/dtos/sync.dto';
|
} from 'src/dtos/sync.dto';
|
||||||
import { AssetVisibility, DatabaseAction, EntityType, Permission, SyncEntityType, SyncRequestType } from 'src/enum';
|
import { AssetVisibility, DatabaseAction, EntityType, Permission, SyncEntityType, SyncRequestType } from 'src/enum';
|
||||||
|
import { SessionSyncCheckpointTable } from 'src/schema/tables/sync-checkpoint.table';
|
||||||
import { BaseService } from 'src/services/base.service';
|
import { BaseService } from 'src/services/base.service';
|
||||||
import { SyncAck } from 'src/types';
|
import { SyncAck } from 'src/types';
|
||||||
import { getMyPartnerIds } from 'src/utils/asset.util';
|
import { getMyPartnerIds } from 'src/utils/asset.util';
|
||||||
@ -90,7 +90,7 @@ export class SyncService extends BaseService {
|
|||||||
return throwSessionRequired();
|
return throwSessionRequired();
|
||||||
}
|
}
|
||||||
|
|
||||||
const checkpoints: Record<string, Insertable<SessionSyncCheckpoints>> = {};
|
const checkpoints: Record<string, Insertable<SessionSyncCheckpointTable>> = {};
|
||||||
for (const ack of dto.acks) {
|
for (const ack of dto.acks) {
|
||||||
const { type } = fromAck(ack);
|
const { type } = fromAck(ack);
|
||||||
// TODO proper ack validation via class validator
|
// TODO proper ack validation via class validator
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { BadRequestException, Injectable } from '@nestjs/common';
|
import { BadRequestException, Injectable } from '@nestjs/common';
|
||||||
import { Insertable } from 'kysely';
|
import { Insertable } from 'kysely';
|
||||||
import { TagAsset } from 'src/db';
|
|
||||||
import { OnJob } from 'src/decorators';
|
import { OnJob } from 'src/decorators';
|
||||||
import { BulkIdResponseDto, BulkIdsDto } from 'src/dtos/asset-ids.response.dto';
|
import { BulkIdResponseDto, BulkIdsDto } from 'src/dtos/asset-ids.response.dto';
|
||||||
import { AuthDto } from 'src/dtos/auth.dto';
|
import { AuthDto } from 'src/dtos/auth.dto';
|
||||||
@ -14,6 +13,7 @@ import {
|
|||||||
mapTag,
|
mapTag,
|
||||||
} from 'src/dtos/tag.dto';
|
} from 'src/dtos/tag.dto';
|
||||||
import { JobName, JobStatus, Permission, QueueName } from 'src/enum';
|
import { JobName, JobStatus, Permission, QueueName } from 'src/enum';
|
||||||
|
import { TagAssetTable } from 'src/schema/tables/tag-asset.table';
|
||||||
import { BaseService } from 'src/services/base.service';
|
import { BaseService } from 'src/services/base.service';
|
||||||
import { addAssets, removeAssets } from 'src/utils/asset.util';
|
import { addAssets, removeAssets } from 'src/utils/asset.util';
|
||||||
import { upsertTags } from 'src/utils/tag';
|
import { upsertTags } from 'src/utils/tag';
|
||||||
@ -81,7 +81,7 @@ export class TagService extends BaseService {
|
|||||||
this.checkAccess({ auth, permission: Permission.ASSET_UPDATE, ids: dto.assetIds }),
|
this.checkAccess({ auth, permission: Permission.ASSET_UPDATE, ids: dto.assetIds }),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const items: Insertable<TagAsset>[] = [];
|
const items: Insertable<TagAssetTable>[] = [];
|
||||||
for (const tagsId of tagIds) {
|
for (const tagsId of tagIds) {
|
||||||
for (const assetsId of assetIds) {
|
for (const assetsId of assetIds) {
|
||||||
items.push({ tagsId, assetsId });
|
items.push({ tagsId, assetsId });
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Kysely } from 'kysely';
|
import { Kysely, ColumnType as KyselyColumnType } from 'kysely';
|
||||||
|
|
||||||
export type PostgresDB = {
|
export type PostgresDB = {
|
||||||
pg_am: {
|
pg_am: {
|
||||||
@ -476,3 +476,10 @@ export enum Reason {
|
|||||||
MissingInSource = 'missing in source',
|
MissingInSource = 'missing in source',
|
||||||
MissingInTarget = 'missing in target',
|
MissingInTarget = 'missing in target',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type Timestamp = KyselyColumnType<Date, Date | string, Date | string>;
|
||||||
|
export type Generated<T> =
|
||||||
|
T extends KyselyColumnType<infer S, infer I, infer U>
|
||||||
|
? KyselyColumnType<S, I | undefined, U>
|
||||||
|
: KyselyColumnType<T, T | undefined, T>;
|
||||||
|
export type Int8 = KyselyColumnType<number>;
|
||||||
|
@ -16,9 +16,9 @@ import { jsonArrayFrom, jsonObjectFrom } from 'kysely/helpers/postgres';
|
|||||||
import { parse } from 'pg-connection-string';
|
import { parse } from 'pg-connection-string';
|
||||||
import postgres, { Notice } from 'postgres';
|
import postgres, { Notice } from 'postgres';
|
||||||
import { columns, Exif, Person } from 'src/database';
|
import { columns, Exif, Person } from 'src/database';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { AssetFileType, AssetVisibility, DatabaseExtension, DatabaseSslMode } from 'src/enum';
|
import { AssetFileType, AssetVisibility, DatabaseExtension, DatabaseSslMode } from 'src/enum';
|
||||||
import { AssetSearchBuilderOptions } from 'src/repositories/search.repository';
|
import { AssetSearchBuilderOptions } from 'src/repositories/search.repository';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
import { DatabaseConnectionParams, VectorExtension } from 'src/types';
|
import { DatabaseConnectionParams, VectorExtension } from 'src/types';
|
||||||
|
|
||||||
type Ssl = 'require' | 'allow' | 'prefer' | 'verify-full' | boolean | object;
|
type Ssl = 'require' | 'allow' | 'prefer' | 'verify-full' | boolean | object;
|
||||||
|
1
server/test/fixtures/asset.stub.ts
vendored
1
server/test/fixtures/asset.stub.ts
vendored
@ -35,6 +35,7 @@ export const stackStub = (stackId: string, assets: (MapAsset & { exifInfo: Exif
|
|||||||
primaryAssetId: assets[0].id,
|
primaryAssetId: assets[0].id,
|
||||||
createdAt: new Date('2023-02-23T05:06:29.716Z'),
|
createdAt: new Date('2023-02-23T05:06:29.716Z'),
|
||||||
updatedAt: new Date('2023-02-23T05:06:29.716Z'),
|
updatedAt: new Date('2023-02-23T05:06:29.716Z'),
|
||||||
|
updateId: 'uuid-v7',
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ import { DateTime } from 'luxon';
|
|||||||
import { createHash, randomBytes } from 'node:crypto';
|
import { createHash, randomBytes } from 'node:crypto';
|
||||||
import { Writable } from 'node:stream';
|
import { Writable } from 'node:stream';
|
||||||
import { AssetFace } from 'src/database';
|
import { AssetFace } from 'src/database';
|
||||||
import { Albums, AssetJobStatus, Assets, DB, Exif, FaceSearch, Memories, Person, Sessions } from 'src/db';
|
|
||||||
import { AuthDto, LoginResponseDto } from 'src/dtos/auth.dto';
|
import { AuthDto, LoginResponseDto } from 'src/dtos/auth.dto';
|
||||||
import { AlbumUserRole, AssetType, AssetVisibility, MemoryType, SourceType, SyncRequestType } from 'src/enum';
|
import { AlbumUserRole, AssetType, AssetVisibility, MemoryType, SourceType, SyncRequestType } from 'src/enum';
|
||||||
import { AccessRepository } from 'src/repositories/access.repository';
|
import { AccessRepository } from 'src/repositories/access.repository';
|
||||||
@ -32,6 +31,15 @@ import { SyncRepository } from 'src/repositories/sync.repository';
|
|||||||
import { SystemMetadataRepository } from 'src/repositories/system-metadata.repository';
|
import { SystemMetadataRepository } from 'src/repositories/system-metadata.repository';
|
||||||
import { UserRepository } from 'src/repositories/user.repository';
|
import { UserRepository } from 'src/repositories/user.repository';
|
||||||
import { VersionHistoryRepository } from 'src/repositories/version-history.repository';
|
import { VersionHistoryRepository } from 'src/repositories/version-history.repository';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
|
import { AlbumTable } from 'src/schema/tables/album.table';
|
||||||
|
import { AssetJobStatusTable } from 'src/schema/tables/asset-job-status.table';
|
||||||
|
import { AssetTable } from 'src/schema/tables/asset.table';
|
||||||
|
import { ExifTable } from 'src/schema/tables/exif.table';
|
||||||
|
import { FaceSearchTable } from 'src/schema/tables/face-search.table';
|
||||||
|
import { MemoryTable } from 'src/schema/tables/memory.table';
|
||||||
|
import { PersonTable } from 'src/schema/tables/person.table';
|
||||||
|
import { SessionTable } from 'src/schema/tables/session.table';
|
||||||
import { UserTable } from 'src/schema/tables/user.table';
|
import { UserTable } from 'src/schema/tables/user.table';
|
||||||
import { BASE_SERVICE_DEPENDENCIES, BaseService } from 'src/services/base.service';
|
import { BASE_SERVICE_DEPENDENCIES, BaseService } from 'src/services/base.service';
|
||||||
import { SyncService } from 'src/services/sync.service';
|
import { SyncService } from 'src/services/sync.service';
|
||||||
@ -125,13 +133,13 @@ export class MediumTestContext<S extends BaseService = BaseService> {
|
|||||||
return { partner, result };
|
return { partner, result };
|
||||||
}
|
}
|
||||||
|
|
||||||
async newAsset(dto: Partial<Insertable<Assets>> = {}) {
|
async newAsset(dto: Partial<Insertable<AssetTable>> = {}) {
|
||||||
const asset = mediumFactory.assetInsert(dto);
|
const asset = mediumFactory.assetInsert(dto);
|
||||||
const result = await this.get(AssetRepository).create(asset);
|
const result = await this.get(AssetRepository).create(asset);
|
||||||
return { asset, result };
|
return { asset, result };
|
||||||
}
|
}
|
||||||
|
|
||||||
async newMemory(dto: Partial<Insertable<Memories>> = {}) {
|
async newMemory(dto: Partial<Insertable<MemoryTable>> = {}) {
|
||||||
const memory = mediumFactory.memoryInsert(dto);
|
const memory = mediumFactory.memoryInsert(dto);
|
||||||
const result = await this.get(MemoryRepository).create(memory, new Set<string>());
|
const result = await this.get(MemoryRepository).create(memory, new Set<string>());
|
||||||
return { memory, result };
|
return { memory, result };
|
||||||
@ -142,12 +150,12 @@ export class MediumTestContext<S extends BaseService = BaseService> {
|
|||||||
return { memoryAsset: dto, result };
|
return { memoryAsset: dto, result };
|
||||||
}
|
}
|
||||||
|
|
||||||
async newExif(dto: Insertable<Exif>) {
|
async newExif(dto: Insertable<ExifTable>) {
|
||||||
const result = await this.get(AssetRepository).upsertExif(dto);
|
const result = await this.get(AssetRepository).upsertExif(dto);
|
||||||
return { result };
|
return { result };
|
||||||
}
|
}
|
||||||
|
|
||||||
async newAlbum(dto: Insertable<Albums>) {
|
async newAlbum(dto: Insertable<AlbumTable>) {
|
||||||
const album = mediumFactory.albumInsert(dto);
|
const album = mediumFactory.albumInsert(dto);
|
||||||
const result = await this.get(AlbumRepository).create(album, [], []);
|
const result = await this.get(AlbumRepository).create(album, [], []);
|
||||||
return { album, result };
|
return { album, result };
|
||||||
@ -164,19 +172,19 @@ export class MediumTestContext<S extends BaseService = BaseService> {
|
|||||||
return { albumUser: { albumId, userId, role }, result };
|
return { albumUser: { albumId, userId, role }, result };
|
||||||
}
|
}
|
||||||
|
|
||||||
async newJobStatus(dto: Partial<Insertable<AssetJobStatus>> & { assetId: string }) {
|
async newJobStatus(dto: Partial<Insertable<AssetJobStatusTable>> & { assetId: string }) {
|
||||||
const jobStatus = mediumFactory.assetJobStatusInsert({ assetId: dto.assetId });
|
const jobStatus = mediumFactory.assetJobStatusInsert({ assetId: dto.assetId });
|
||||||
const result = await this.get(AssetRepository).upsertJobStatus(jobStatus);
|
const result = await this.get(AssetRepository).upsertJobStatus(jobStatus);
|
||||||
return { jobStatus, result };
|
return { jobStatus, result };
|
||||||
}
|
}
|
||||||
|
|
||||||
async newPerson(dto: Partial<Insertable<Person>> & { ownerId: string }) {
|
async newPerson(dto: Partial<Insertable<PersonTable>> & { ownerId: string }) {
|
||||||
const person = mediumFactory.personInsert(dto);
|
const person = mediumFactory.personInsert(dto);
|
||||||
const result = await this.get(PersonRepository).create(person);
|
const result = await this.get(PersonRepository).create(person);
|
||||||
return { person, result };
|
return { person, result };
|
||||||
}
|
}
|
||||||
|
|
||||||
async newSession(dto: Partial<Insertable<Sessions>> & { userId: string }) {
|
async newSession(dto: Partial<Insertable<SessionTable>> & { userId: string }) {
|
||||||
const session = mediumFactory.sessionInsert(dto);
|
const session = mediumFactory.sessionInsert(dto);
|
||||||
const result = await this.get(SessionRepository).create(session);
|
const result = await this.get(SessionRepository).create(session);
|
||||||
return { session, result };
|
return { session, result };
|
||||||
@ -338,10 +346,10 @@ const newMockRepository = <T>(key: ClassConstructor<T>) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const assetInsert = (asset: Partial<Insertable<Assets>> = {}) => {
|
const assetInsert = (asset: Partial<Insertable<AssetTable>> = {}) => {
|
||||||
const id = asset.id || newUuid();
|
const id = asset.id || newUuid();
|
||||||
const now = newDate();
|
const now = newDate();
|
||||||
const defaults: Insertable<Assets> = {
|
const defaults: Insertable<AssetTable> = {
|
||||||
deviceAssetId: '',
|
deviceAssetId: '',
|
||||||
deviceId: '',
|
deviceId: '',
|
||||||
originalFileName: '',
|
originalFileName: '',
|
||||||
@ -363,9 +371,9 @@ const assetInsert = (asset: Partial<Insertable<Assets>> = {}) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const albumInsert = (album: Partial<Insertable<Albums>> & { ownerId: string }) => {
|
const albumInsert = (album: Partial<Insertable<AlbumTable>> & { ownerId: string }) => {
|
||||||
const id = album.id || newUuid();
|
const id = album.id || newUuid();
|
||||||
const defaults: Omit<Insertable<Albums>, 'ownerId'> = {
|
const defaults: Omit<Insertable<AlbumTable>, 'ownerId'> = {
|
||||||
albumName: 'Album',
|
albumName: 'Album',
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -376,7 +384,7 @@ const albumInsert = (album: Partial<Insertable<Albums>> & { ownerId: string }) =
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const faceInsert = (face: Partial<Insertable<FaceSearch>> & { faceId: string }) => {
|
const faceInsert = (face: Partial<Insertable<FaceSearchTable>> & { faceId: string }) => {
|
||||||
const defaults = {
|
const defaults = {
|
||||||
faceId: face.faceId,
|
faceId: face.faceId,
|
||||||
embedding: face.embedding || newEmbedding(),
|
embedding: face.embedding || newEmbedding(),
|
||||||
@ -409,10 +417,10 @@ const assetFaceInsert = (assetFace: Partial<AssetFace> & { assetId: string }) =>
|
|||||||
};
|
};
|
||||||
|
|
||||||
const assetJobStatusInsert = (
|
const assetJobStatusInsert = (
|
||||||
job: Partial<Insertable<AssetJobStatus>> & { assetId: string },
|
job: Partial<Insertable<AssetJobStatusTable>> & { assetId: string },
|
||||||
): Insertable<AssetJobStatus> => {
|
): Insertable<AssetJobStatusTable> => {
|
||||||
const date = DateTime.now().minus({ days: 15 }).toISO();
|
const date = DateTime.now().minus({ days: 15 }).toISO();
|
||||||
const defaults: Omit<Insertable<AssetJobStatus>, 'assetId'> = {
|
const defaults: Omit<Insertable<AssetJobStatusTable>, 'assetId'> = {
|
||||||
duplicatesDetectedAt: date,
|
duplicatesDetectedAt: date,
|
||||||
facesRecognizedAt: date,
|
facesRecognizedAt: date,
|
||||||
metadataExtractedAt: date,
|
metadataExtractedAt: date,
|
||||||
@ -426,7 +434,7 @@ const assetJobStatusInsert = (
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const personInsert = (person: Partial<Insertable<Person>> & { ownerId: string }) => {
|
const personInsert = (person: Partial<Insertable<PersonTable>> & { ownerId: string }) => {
|
||||||
const defaults = {
|
const defaults = {
|
||||||
birthDate: person.birthDate || null,
|
birthDate: person.birthDate || null,
|
||||||
color: person.color || null,
|
color: person.color || null,
|
||||||
@ -449,8 +457,12 @@ const personInsert = (person: Partial<Insertable<Person>> & { ownerId: string })
|
|||||||
|
|
||||||
const sha256 = (value: string) => createHash('sha256').update(value).digest('base64');
|
const sha256 = (value: string) => createHash('sha256').update(value).digest('base64');
|
||||||
|
|
||||||
const sessionInsert = ({ id = newUuid(), userId, ...session }: Partial<Insertable<Sessions>> & { userId: string }) => {
|
const sessionInsert = ({
|
||||||
const defaults: Insertable<Sessions> = {
|
id = newUuid(),
|
||||||
|
userId,
|
||||||
|
...session
|
||||||
|
}: Partial<Insertable<SessionTable>> & { userId: string }) => {
|
||||||
|
const defaults: Insertable<SessionTable> = {
|
||||||
id,
|
id,
|
||||||
userId,
|
userId,
|
||||||
token: sha256(id),
|
token: sha256(id),
|
||||||
@ -478,11 +490,11 @@ const userInsert = (user: Partial<Insertable<UserTable>> = {}) => {
|
|||||||
return { ...defaults, ...user, id };
|
return { ...defaults, ...user, id };
|
||||||
};
|
};
|
||||||
|
|
||||||
const memoryInsert = (memory: Partial<Insertable<Memories>> = {}) => {
|
const memoryInsert = (memory: Partial<Insertable<MemoryTable>> = {}) => {
|
||||||
const id = memory.id || newUuid();
|
const id = memory.id || newUuid();
|
||||||
const date = newDate();
|
const date = newDate();
|
||||||
|
|
||||||
const defaults: Insertable<Memories> = {
|
const defaults: Insertable<MemoryTable> = {
|
||||||
id,
|
id,
|
||||||
createdAt: date,
|
createdAt: date,
|
||||||
updatedAt: date,
|
updatedAt: date,
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { Kysely } from 'kysely';
|
import { Kysely } from 'kysely';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { ConfigRepository } from 'src/repositories/config.repository';
|
import { ConfigRepository } from 'src/repositories/config.repository';
|
||||||
import { DatabaseRepository } from 'src/repositories/database.repository';
|
import { DatabaseRepository } from 'src/repositories/database.repository';
|
||||||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
import { getKyselyConfig } from 'src/utils/database';
|
import { getKyselyConfig } from 'src/utils/database';
|
||||||
import { GenericContainer, Wait } from 'testcontainers';
|
import { GenericContainer, Wait } from 'testcontainers';
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Kysely } from 'kysely';
|
import { Kysely } from 'kysely';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { AssetRepository } from 'src/repositories/asset.repository';
|
import { AssetRepository } from 'src/repositories/asset.repository';
|
||||||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
import { AssetService } from 'src/services/asset.service';
|
import { AssetService } from 'src/services/asset.service';
|
||||||
import { newMediumService } from 'test/medium.factory';
|
import { newMediumService } from 'test/medium.factory';
|
||||||
import { factory } from 'test/small.factory';
|
import { factory } from 'test/small.factory';
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { BadRequestException } from '@nestjs/common';
|
import { BadRequestException } from '@nestjs/common';
|
||||||
import { hash } from 'bcrypt';
|
import { hash } from 'bcrypt';
|
||||||
import { Kysely } from 'kysely';
|
import { Kysely } from 'kysely';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { AuthType } from 'src/enum';
|
import { AuthType } from 'src/enum';
|
||||||
import { AccessRepository } from 'src/repositories/access.repository';
|
import { AccessRepository } from 'src/repositories/access.repository';
|
||||||
import { ConfigRepository } from 'src/repositories/config.repository';
|
import { ConfigRepository } from 'src/repositories/config.repository';
|
||||||
@ -13,6 +12,7 @@ import { SessionRepository } from 'src/repositories/session.repository';
|
|||||||
import { StorageRepository } from 'src/repositories/storage.repository';
|
import { StorageRepository } from 'src/repositories/storage.repository';
|
||||||
import { SystemMetadataRepository } from 'src/repositories/system-metadata.repository';
|
import { SystemMetadataRepository } from 'src/repositories/system-metadata.repository';
|
||||||
import { UserRepository } from 'src/repositories/user.repository';
|
import { UserRepository } from 'src/repositories/user.repository';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
import { AuthService } from 'src/services/auth.service';
|
import { AuthService } from 'src/services/auth.service';
|
||||||
import { mediumFactory, newMediumService } from 'test/medium.factory';
|
import { mediumFactory, newMediumService } from 'test/medium.factory';
|
||||||
import { factory } from 'test/small.factory';
|
import { factory } from 'test/small.factory';
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { Kysely } from 'kysely';
|
import { Kysely } from 'kysely';
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { AssetFileType, MemoryType } from 'src/enum';
|
import { AssetFileType, MemoryType } from 'src/enum';
|
||||||
import { AccessRepository } from 'src/repositories/access.repository';
|
import { AccessRepository } from 'src/repositories/access.repository';
|
||||||
import { AssetRepository } from 'src/repositories/asset.repository';
|
import { AssetRepository } from 'src/repositories/asset.repository';
|
||||||
@ -10,6 +9,7 @@ import { MemoryRepository } from 'src/repositories/memory.repository';
|
|||||||
import { PartnerRepository } from 'src/repositories/partner.repository';
|
import { PartnerRepository } from 'src/repositories/partner.repository';
|
||||||
import { SystemMetadataRepository } from 'src/repositories/system-metadata.repository';
|
import { SystemMetadataRepository } from 'src/repositories/system-metadata.repository';
|
||||||
import { UserRepository } from 'src/repositories/user.repository';
|
import { UserRepository } from 'src/repositories/user.repository';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
import { MemoryService } from 'src/services/memory.service';
|
import { MemoryService } from 'src/services/memory.service';
|
||||||
import { newMediumService } from 'test/medium.factory';
|
import { newMediumService } from 'test/medium.factory';
|
||||||
import { factory } from 'test/small.factory';
|
import { factory } from 'test/small.factory';
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { Kysely } from 'kysely';
|
import { Kysely } from 'kysely';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { AccessRepository } from 'src/repositories/access.repository';
|
import { AccessRepository } from 'src/repositories/access.repository';
|
||||||
import { DatabaseRepository } from 'src/repositories/database.repository';
|
import { DatabaseRepository } from 'src/repositories/database.repository';
|
||||||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||||
import { PersonRepository } from 'src/repositories/person.repository';
|
import { PersonRepository } from 'src/repositories/person.repository';
|
||||||
import { StorageRepository } from 'src/repositories/storage.repository';
|
import { StorageRepository } from 'src/repositories/storage.repository';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
import { PersonService } from 'src/services/person.service';
|
import { PersonService } from 'src/services/person.service';
|
||||||
import { newMediumService } from 'test/medium.factory';
|
import { newMediumService } from 'test/medium.factory';
|
||||||
import { factory } from 'test/small.factory';
|
import { factory } from 'test/small.factory';
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { Kysely } from 'kysely';
|
import { Kysely } from 'kysely';
|
||||||
import { DateTime } from 'luxon';
|
import { DateTime } from 'luxon';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { ImmichEnvironment, JobName, JobStatus } from 'src/enum';
|
import { ImmichEnvironment, JobName, JobStatus } from 'src/enum';
|
||||||
import { ConfigRepository } from 'src/repositories/config.repository';
|
import { ConfigRepository } from 'src/repositories/config.repository';
|
||||||
import { CryptoRepository } from 'src/repositories/crypto.repository';
|
import { CryptoRepository } from 'src/repositories/crypto.repository';
|
||||||
@ -8,6 +7,7 @@ import { JobRepository } from 'src/repositories/job.repository';
|
|||||||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||||
import { SystemMetadataRepository } from 'src/repositories/system-metadata.repository';
|
import { SystemMetadataRepository } from 'src/repositories/system-metadata.repository';
|
||||||
import { UserRepository } from 'src/repositories/user.repository';
|
import { UserRepository } from 'src/repositories/user.repository';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
import { UserService } from 'src/services/user.service';
|
import { UserService } from 'src/services/user.service';
|
||||||
import { mediumFactory, newMediumService } from 'test/medium.factory';
|
import { mediumFactory, newMediumService } from 'test/medium.factory';
|
||||||
import { factory } from 'test/small.factory';
|
import { factory } from 'test/small.factory';
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { Kysely } from 'kysely';
|
import { Kysely } from 'kysely';
|
||||||
import { serverVersion } from 'src/constants';
|
import { serverVersion } from 'src/constants';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { JobName } from 'src/enum';
|
import { JobName } from 'src/enum';
|
||||||
import { DatabaseRepository } from 'src/repositories/database.repository';
|
import { DatabaseRepository } from 'src/repositories/database.repository';
|
||||||
import { JobRepository } from 'src/repositories/job.repository';
|
import { JobRepository } from 'src/repositories/job.repository';
|
||||||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||||
import { VersionHistoryRepository } from 'src/repositories/version-history.repository';
|
import { VersionHistoryRepository } from 'src/repositories/version-history.repository';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
import { VersionService } from 'src/services/version.service';
|
import { VersionService } from 'src/services/version.service';
|
||||||
import { newMediumService } from 'test/medium.factory';
|
import { newMediumService } from 'test/medium.factory';
|
||||||
import { getKyselyDB } from 'test/utils';
|
import { getKyselyDB } from 'test/utils';
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Kysely } from 'kysely';
|
import { Kysely } from 'kysely';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { AlbumUserRole, SyncEntityType, SyncRequestType } from 'src/enum';
|
import { AlbumUserRole, SyncEntityType, SyncRequestType } from 'src/enum';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
import { SyncTestContext } from 'test/medium.factory';
|
import { SyncTestContext } from 'test/medium.factory';
|
||||||
import { factory } from 'test/small.factory';
|
import { factory } from 'test/small.factory';
|
||||||
import { getKyselyDB, wait } from 'test/utils';
|
import { getKyselyDB, wait } from 'test/utils';
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Kysely } from 'kysely';
|
import { Kysely } from 'kysely';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { AlbumUserRole, SyncEntityType, SyncRequestType } from 'src/enum';
|
import { AlbumUserRole, SyncEntityType, SyncRequestType } from 'src/enum';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
import { SyncTestContext } from 'test/medium.factory';
|
import { SyncTestContext } from 'test/medium.factory';
|
||||||
import { factory } from 'test/small.factory';
|
import { factory } from 'test/small.factory';
|
||||||
import { getKyselyDB, wait } from 'test/utils';
|
import { getKyselyDB, wait } from 'test/utils';
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { Kysely } from 'kysely';
|
import { Kysely } from 'kysely';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { AlbumUserRole, SyncEntityType, SyncRequestType } from 'src/enum';
|
import { AlbumUserRole, SyncEntityType, SyncRequestType } from 'src/enum';
|
||||||
import { AlbumRepository } from 'src/repositories/album.repository';
|
import { AlbumRepository } from 'src/repositories/album.repository';
|
||||||
import { AssetRepository } from 'src/repositories/asset.repository';
|
import { AssetRepository } from 'src/repositories/asset.repository';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
import { SyncTestContext } from 'test/medium.factory';
|
import { SyncTestContext } from 'test/medium.factory';
|
||||||
import { getKyselyDB, wait } from 'test/utils';
|
import { getKyselyDB, wait } from 'test/utils';
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Kysely } from 'kysely';
|
import { Kysely } from 'kysely';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { AlbumUserRole, SyncEntityType, SyncRequestType } from 'src/enum';
|
import { AlbumUserRole, SyncEntityType, SyncRequestType } from 'src/enum';
|
||||||
import { AlbumUserRepository } from 'src/repositories/album-user.repository';
|
import { AlbumUserRepository } from 'src/repositories/album-user.repository';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
import { SyncTestContext } from 'test/medium.factory';
|
import { SyncTestContext } from 'test/medium.factory';
|
||||||
import { getKyselyDB, wait } from 'test/utils';
|
import { getKyselyDB, wait } from 'test/utils';
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { Kysely } from 'kysely';
|
import { Kysely } from 'kysely';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { AlbumUserRole, SyncEntityType, SyncRequestType } from 'src/enum';
|
import { AlbumUserRole, SyncEntityType, SyncRequestType } from 'src/enum';
|
||||||
import { AlbumUserRepository } from 'src/repositories/album-user.repository';
|
import { AlbumUserRepository } from 'src/repositories/album-user.repository';
|
||||||
import { AlbumRepository } from 'src/repositories/album.repository';
|
import { AlbumRepository } from 'src/repositories/album.repository';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
import { SyncTestContext } from 'test/medium.factory';
|
import { SyncTestContext } from 'test/medium.factory';
|
||||||
import { getKyselyDB } from 'test/utils';
|
import { getKyselyDB } from 'test/utils';
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Kysely } from 'kysely';
|
import { Kysely } from 'kysely';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { SyncEntityType, SyncRequestType } from 'src/enum';
|
import { SyncEntityType, SyncRequestType } from 'src/enum';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
import { SyncTestContext } from 'test/medium.factory';
|
import { SyncTestContext } from 'test/medium.factory';
|
||||||
import { factory } from 'test/small.factory';
|
import { factory } from 'test/small.factory';
|
||||||
import { getKyselyDB } from 'test/utils';
|
import { getKyselyDB } from 'test/utils';
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Kysely } from 'kysely';
|
import { Kysely } from 'kysely';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { SyncEntityType, SyncRequestType } from 'src/enum';
|
import { SyncEntityType, SyncRequestType } from 'src/enum';
|
||||||
import { AssetRepository } from 'src/repositories/asset.repository';
|
import { AssetRepository } from 'src/repositories/asset.repository';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
import { SyncTestContext } from 'test/medium.factory';
|
import { SyncTestContext } from 'test/medium.factory';
|
||||||
import { factory } from 'test/small.factory';
|
import { factory } from 'test/small.factory';
|
||||||
import { getKyselyDB } from 'test/utils';
|
import { getKyselyDB } from 'test/utils';
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Kysely } from 'kysely';
|
import { Kysely } from 'kysely';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { SyncEntityType, SyncRequestType } from 'src/enum';
|
import { SyncEntityType, SyncRequestType } from 'src/enum';
|
||||||
import { MemoryRepository } from 'src/repositories/memory.repository';
|
import { MemoryRepository } from 'src/repositories/memory.repository';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
import { SyncTestContext } from 'test/medium.factory';
|
import { SyncTestContext } from 'test/medium.factory';
|
||||||
import { getKyselyDB } from 'test/utils';
|
import { getKyselyDB } from 'test/utils';
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Kysely } from 'kysely';
|
import { Kysely } from 'kysely';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { SyncEntityType, SyncRequestType } from 'src/enum';
|
import { SyncEntityType, SyncRequestType } from 'src/enum';
|
||||||
import { MemoryRepository } from 'src/repositories/memory.repository';
|
import { MemoryRepository } from 'src/repositories/memory.repository';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
import { SyncTestContext } from 'test/medium.factory';
|
import { SyncTestContext } from 'test/medium.factory';
|
||||||
import { getKyselyDB } from 'test/utils';
|
import { getKyselyDB } from 'test/utils';
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Kysely } from 'kysely';
|
import { Kysely } from 'kysely';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { SyncEntityType, SyncRequestType } from 'src/enum';
|
import { SyncEntityType, SyncRequestType } from 'src/enum';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
import { SyncTestContext } from 'test/medium.factory';
|
import { SyncTestContext } from 'test/medium.factory';
|
||||||
import { factory } from 'test/small.factory';
|
import { factory } from 'test/small.factory';
|
||||||
import { getKyselyDB, wait } from 'test/utils';
|
import { getKyselyDB, wait } from 'test/utils';
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { Kysely } from 'kysely';
|
import { Kysely } from 'kysely';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { SyncEntityType, SyncRequestType } from 'src/enum';
|
import { SyncEntityType, SyncRequestType } from 'src/enum';
|
||||||
import { AssetRepository } from 'src/repositories/asset.repository';
|
import { AssetRepository } from 'src/repositories/asset.repository';
|
||||||
import { PartnerRepository } from 'src/repositories/partner.repository';
|
import { PartnerRepository } from 'src/repositories/partner.repository';
|
||||||
import { UserRepository } from 'src/repositories/user.repository';
|
import { UserRepository } from 'src/repositories/user.repository';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
import { SyncTestContext } from 'test/medium.factory';
|
import { SyncTestContext } from 'test/medium.factory';
|
||||||
import { factory } from 'test/small.factory';
|
import { factory } from 'test/small.factory';
|
||||||
import { getKyselyDB, wait } from 'test/utils';
|
import { getKyselyDB, wait } from 'test/utils';
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { Kysely } from 'kysely';
|
import { Kysely } from 'kysely';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { SyncEntityType, SyncRequestType } from 'src/enum';
|
import { SyncEntityType, SyncRequestType } from 'src/enum';
|
||||||
import { PartnerRepository } from 'src/repositories/partner.repository';
|
import { PartnerRepository } from 'src/repositories/partner.repository';
|
||||||
import { UserRepository } from 'src/repositories/user.repository';
|
import { UserRepository } from 'src/repositories/user.repository';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
import { SyncTestContext } from 'test/medium.factory';
|
import { SyncTestContext } from 'test/medium.factory';
|
||||||
import { getKyselyDB } from 'test/utils';
|
import { getKyselyDB } from 'test/utils';
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Kysely } from 'kysely';
|
import { Kysely } from 'kysely';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { SyncEntityType, SyncRequestType } from 'src/enum';
|
import { SyncEntityType, SyncRequestType } from 'src/enum';
|
||||||
import { UserRepository } from 'src/repositories/user.repository';
|
import { UserRepository } from 'src/repositories/user.repository';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
import { SyncTestContext } from 'test/medium.factory';
|
import { SyncTestContext } from 'test/medium.factory';
|
||||||
import { getKyselyDB } from 'test/utils';
|
import { getKyselyDB } from 'test/utils';
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@ import { ChildProcessWithoutNullStreams } from 'node:child_process';
|
|||||||
import { Writable } from 'node:stream';
|
import { Writable } from 'node:stream';
|
||||||
import { PNG } from 'pngjs';
|
import { PNG } from 'pngjs';
|
||||||
import postgres from 'postgres';
|
import postgres from 'postgres';
|
||||||
import { DB } from 'src/db';
|
|
||||||
import { AssetUploadInterceptor } from 'src/middleware/asset-upload.interceptor';
|
import { AssetUploadInterceptor } from 'src/middleware/asset-upload.interceptor';
|
||||||
import { AuthGuard } from 'src/middleware/auth.guard';
|
import { AuthGuard } from 'src/middleware/auth.guard';
|
||||||
import { FileUploadInterceptor } from 'src/middleware/file-upload.interceptor';
|
import { FileUploadInterceptor } from 'src/middleware/file-upload.interceptor';
|
||||||
@ -56,6 +55,7 @@ import { TrashRepository } from 'src/repositories/trash.repository';
|
|||||||
import { UserRepository } from 'src/repositories/user.repository';
|
import { UserRepository } from 'src/repositories/user.repository';
|
||||||
import { VersionHistoryRepository } from 'src/repositories/version-history.repository';
|
import { VersionHistoryRepository } from 'src/repositories/version-history.repository';
|
||||||
import { ViewRepository } from 'src/repositories/view-repository';
|
import { ViewRepository } from 'src/repositories/view-repository';
|
||||||
|
import { DB } from 'src/schema';
|
||||||
import { AuthService } from 'src/services/auth.service';
|
import { AuthService } from 'src/services/auth.service';
|
||||||
import { BaseService } from 'src/services/base.service';
|
import { BaseService } from 'src/services/base.service';
|
||||||
import { RepositoryInterface } from 'src/types';
|
import { RepositoryInterface } from 'src/types';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user