refactor: database types (#19624)

This commit is contained in:
Jason Rasmussen
2025-06-30 13:19:16 -04:00
committed by GitHub
parent 09cbc5d3f4
commit e60bc3c304
99 changed files with 518 additions and 889 deletions

View File

@@ -1,9 +1,9 @@
import { Injectable } from '@nestjs/common';
import { Kysely, sql } from 'kysely';
import { InjectKysely } from 'nestjs-kysely';
import { DB } from 'src/db';
import { ChunkedSet, DummyValue, GenerateSql } from 'src/decorators';
import { AlbumUserRole, AssetVisibility } from 'src/enum';
import { DB } from 'src/schema';
import { asUuid } from 'src/utils/database';
class ActivityAccess {

View File

@@ -3,9 +3,10 @@ import { Insertable, Kysely, NotNull, sql } from 'kysely';
import { jsonObjectFrom } from 'kysely/helpers/postgres';
import { InjectKysely } from 'nestjs-kysely';
import { columns } from 'src/database';
import { Activity, DB } from 'src/db';
import { DummyValue, GenerateSql } from 'src/decorators';
import { AssetVisibility } from 'src/enum';
import { DB } from 'src/schema';
import { ActivityTable } from 'src/schema/tables/activity.table';
import { asUuid } from 'src/utils/database';
export interface ActivitySearch {
@@ -48,7 +49,7 @@ export class ActivityRepository {
}
@GenerateSql({ params: [{ albumId: DummyValue.UUID, userId: DummyValue.UUID }] })
async create(activity: Insertable<Activity>) {
async create(activity: Insertable<ActivityTable>) {
return this.db
.insertInto('activity')
.values(activity)

View File

@@ -1,9 +1,10 @@
import { Injectable } from '@nestjs/common';
import { Insertable, Kysely, Updateable } from 'kysely';
import { InjectKysely } from 'nestjs-kysely';
import { AlbumsSharedUsersUsers, DB } from 'src/db';
import { DummyValue, GenerateSql } from 'src/decorators';
import { AlbumUserRole } from 'src/enum';
import { DB } from 'src/schema';
import { AlbumUserTable } from 'src/schema/tables/album-user.table';
export type AlbumPermissionId = {
albumsId: string;
@@ -15,7 +16,7 @@ export class AlbumUserRepository {
constructor(@InjectKysely() private db: Kysely<DB>) {}
@GenerateSql({ params: [{ usersId: DummyValue.UUID, albumsId: DummyValue.UUID }] })
create(albumUser: Insertable<AlbumsSharedUsersUsers>) {
create(albumUser: Insertable<AlbumUserTable>) {
return this.db
.insertInto('albums_shared_users_users')
.values(albumUser)
@@ -24,7 +25,7 @@ export class AlbumUserRepository {
}
@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
.updateTable('albums_shared_users_users')
.set(dto)

View File

@@ -3,9 +3,10 @@ import { ExpressionBuilder, Insertable, Kysely, NotNull, sql, Updateable } from
import { jsonArrayFrom, jsonObjectFrom } from 'kysely/helpers/postgres';
import { InjectKysely } from 'nestjs-kysely';
import { columns, Exif } from 'src/database';
import { Albums, DB } from 'src/db';
import { Chunked, ChunkedArray, ChunkedSet, DummyValue, GenerateSql } from 'src/decorators';
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';
export interface AlbumAssetCount {
@@ -269,7 +270,7 @@ export class AlbumRepository {
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) => {
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
.updateTable('albums')
.set(album)

View File

@@ -3,19 +3,20 @@ import { Insertable, Kysely, Updateable } from 'kysely';
import { jsonObjectFrom } from 'kysely/helpers/postgres';
import { InjectKysely } from 'nestjs-kysely';
import { columns } from 'src/database';
import { ApiKeys, DB } from 'src/db';
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';
@Injectable()
export class ApiKeyRepository {
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();
}
async update(userId: string, id: string, dto: Updateable<ApiKeys>) {
async update(userId: string, id: string, dto: Updateable<ApiKeyTable>) {
return this.db
.updateTable('api_keys')
.set(dto)

View File

@@ -3,9 +3,9 @@ import { Kysely } from 'kysely';
import { jsonArrayFrom } from 'kysely/helpers/postgres';
import { InjectKysely } from 'nestjs-kysely';
import { Asset, columns } from 'src/database';
import { DB } from 'src/db';
import { DummyValue, GenerateSql } from 'src/decorators';
import { AssetFileType, AssetType, AssetVisibility } from 'src/enum';
import { DB } from 'src/schema';
import { StorageAsset } from 'src/types';
import {
anyUuid,

View File

@@ -3,9 +3,13 @@ import { Insertable, Kysely, NotNull, Selectable, UpdateResult, Updateable, sql
import { isEmpty, isUndefined, omitBy } from 'lodash';
import { InjectKysely } from 'nestjs-kysely';
import { Stack } from 'src/database';
import { AssetFiles, AssetJobStatus, Assets, DB, Exif } from 'src/db';
import { Chunked, ChunkedArray, DummyValue, GenerateSql } from 'src/decorators';
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 {
anyUuid,
asUuid,
@@ -110,7 +114,7 @@ interface GetByIdsRelations {
export class AssetRepository {
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) };
await this.db
.insertInto('exif')
@@ -157,7 +161,7 @@ export class AssetRepository {
@GenerateSql({ params: [[DummyValue.UUID], { model: DummyValue.STRING }] })
@Chunked()
async updateAllExif(ids: string[], options: Updateable<Exif>): Promise<void> {
async updateAllExif(ids: string[], options: Updateable<ExifTable>): Promise<void> {
if (ids.length === 0) {
return;
}
@@ -165,7 +169,7 @@ export class AssetRepository {
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) {
return;
}
@@ -191,11 +195,11 @@ export class AssetRepository {
.execute();
}
create(asset: Insertable<Assets>) {
create(asset: Insertable<AssetTable>) {
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();
}
@@ -375,18 +379,18 @@ export class AssetRepository {
@GenerateSql({ params: [[DummyValue.UUID], { deviceId: DummyValue.STRING }] })
@Chunked()
async updateAll(ids: string[], options: Updateable<Assets>): Promise<void> {
async updateAll(ids: string[], options: Updateable<AssetTable>): Promise<void> {
if (ids.length === 0) {
return;
}
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();
}
async update(asset: Updateable<Assets> & { id: string }) {
async update(asset: Updateable<AssetTable> & { id: string }) {
const value = omitBy(asset, isUndefined);
delete value.id;
if (!isEmpty(value)) {
@@ -742,7 +746,7 @@ export class AssetRepository {
.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) };
await this.db
.insertInto('asset_files')
@@ -755,7 +759,7 @@ export class AssetRepository {
.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) {
return;
}
@@ -772,7 +776,7 @@ export class AssetRepository {
.execute();
}
async deleteFiles(files: Pick<Selectable<AssetFiles>, 'id'>[]): Promise<void> {
async deleteFiles(files: Pick<Selectable<AssetFileTable>, 'id'>[]): Promise<void> {
if (files.length === 0) {
return;
}

View File

@@ -1,9 +1,9 @@
import { Injectable } from '@nestjs/common';
import { Kysely } from 'kysely';
import { InjectKysely } from 'nestjs-kysely';
import { DB } from 'src/db';
import { DummyValue, GenerateSql } from 'src/decorators';
import { DatabaseAction, EntityType } from 'src/enum';
import { DB } from 'src/schema';
export interface AuditSearch {
action?: DatabaseAction;

View File

@@ -15,11 +15,11 @@ import {
VECTORCHORD_VERSION_RANGE,
VECTORS_VERSION_RANGE,
} from 'src/constants';
import { DB } from 'src/db';
import { GenerateSql } from 'src/decorators';
import { DatabaseExtension, DatabaseLock, VectorIndex } from 'src/enum';
import { ConfigRepository } from 'src/repositories/config.repository';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { DB } from 'src/schema';
import { ExtensionVersion, VectorExtension, VectorUpdateResult } from 'src/types';
import { vectorIndexQuery } from 'src/utils/database';
import { isValidInteger } from 'src/validation';

View File

@@ -1,8 +1,8 @@
import { Injectable } from '@nestjs/common';
import { Kysely } from 'kysely';
import { InjectKysely } from 'nestjs-kysely';
import { DB } from 'src/db';
import { AssetVisibility } from 'src/enum';
import { DB } from 'src/schema';
import { anyUuid } from 'src/utils/database';
const builder = (db: Kysely<DB>) =>

View File

@@ -1,11 +1,11 @@
import { Injectable } from '@nestjs/common';
import { Kysely, NotNull, sql } from 'kysely';
import { InjectKysely } from 'nestjs-kysely';
import { DB } from 'src/db';
import { Chunked, DummyValue, GenerateSql } from 'src/decorators';
import { MapAsset } from 'src/dtos/asset-response.dto';
import { AssetType, VectorIndex } from 'src/enum';
import { probes } from 'src/repositories/database.repository';
import { DB } from 'src/schema';
import { anyUuid, asUuid, withDefaultVisibility } from 'src/utils/database';
interface DuplicateSearch {

View File

@@ -1,10 +1,11 @@
import { Injectable } from '@nestjs/common';
import { Insertable, Kysely, sql, Updateable } from 'kysely';
import { InjectKysely } from 'nestjs-kysely';
import { DB, Libraries } from 'src/db';
import { DummyValue, GenerateSql } from 'src/decorators';
import { LibraryStatsResponseDto } from 'src/dtos/library.dto';
import { AssetType, AssetVisibility } from 'src/enum';
import { DB } from 'src/schema';
import { LibraryTable } from 'src/schema/tables/library.table';
export enum AssetSyncResult {
DO_NOTHING,
@@ -47,7 +48,7 @@ export class LibraryRepository {
.execute();
}
create(library: Insertable<Libraries>) {
create(library: Insertable<LibraryTable>) {
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();
}
update(id: string, library: Updateable<Libraries>) {
update(id: string, library: Updateable<LibraryTable>) {
return this.db
.updateTable('libraries')
.set(library)

View File

@@ -6,12 +6,14 @@ import { createReadStream, existsSync } from 'node:fs';
import { readFile } from 'node:fs/promises';
import readLine from 'node:readline';
import { citiesFile } from 'src/constants';
import { DB, GeodataPlaces, NaturalearthCountries } from 'src/db';
import { DummyValue, GenerateSql } from 'src/decorators';
import { AssetVisibility, SystemMetadataKey } from 'src/enum';
import { ConfigRepository } from 'src/repositories/config.repository';
import { LoggingRepository } from 'src/repositories/logging.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 {
isArchived?: boolean;
@@ -38,8 +40,8 @@ export interface MapMarker extends ReverseGeocodeResult {
}
interface MapDB extends DB {
geodata_places_tmp: GeodataPlaces;
naturalearth_countries_tmp: NaturalearthCountries;
geodata_places_tmp: GeodataPlacesTable;
naturalearth_countries_tmp: NaturalEarthCountriesTable;
}
@Injectable()
@@ -193,11 +195,11 @@ export class MapRepository {
return;
}
const entities: Insertable<NaturalearthCountries>[] = [];
const entities: Insertable<NaturalEarthCountriesTable>[] = [];
for (const feature of geoJSONData.features) {
for (const entry of feature.geometry.coordinates) {
const coordinates: number[][][] = feature.geometry.type === 'MultiPolygon' ? entry[0] : entry;
const featureRecord: Insertable<NaturalearthCountries> = {
const featureRecord: Insertable<NaturalEarthCountriesTable> = {
admin: feature.properties.ADMIN,
admin_a3: feature.properties.ADM0_A3,
type: feature.properties.TYPE,

View File

@@ -3,10 +3,11 @@ import { Insertable, Kysely, sql, Updateable } from 'kysely';
import { jsonArrayFrom } from 'kysely/helpers/postgres';
import { DateTime } from 'luxon';
import { InjectKysely } from 'nestjs-kysely';
import { DB, Memories } from 'src/db';
import { Chunked, ChunkedSet, DummyValue, GenerateSql } from 'src/decorators';
import { MemorySearchDto } from 'src/dtos/memory.dto';
import { AssetVisibility } from 'src/enum';
import { DB } from 'src/schema';
import { MemoryTable } from 'src/schema/tables/memory.table';
import { IBulkAsset } from 'src/types';
@Injectable()
@@ -80,7 +81,7 @@ export class MemoryRepository implements IBulkAsset {
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 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 }] })
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();
return this.getByIdBuilder(id).executeTakeFirstOrThrow();
}

View File

@@ -1,15 +1,16 @@
import { Injectable } from '@nestjs/common';
import { Insertable, Kysely, sql, Updateable } from 'kysely';
import { InjectKysely } from 'nestjs-kysely';
import { DB, MoveHistory } from 'src/db';
import { DummyValue, GenerateSql } from 'src/decorators';
import { AssetPathType, PathType } from 'src/enum';
import { DB } from 'src/schema';
import { MoveTable } from 'src/schema/tables/move.table';
@Injectable()
export class MoveRepository {
constructor(@InjectKysely() private db: Kysely<DB>) {}
create(entity: Insertable<MoveHistory>) {
create(entity: Insertable<MoveTable>) {
return this.db.insertInto('move_history').values(entity).returningAll().executeTakeFirstOrThrow();
}
@@ -23,7 +24,7 @@ export class MoveRepository {
.executeTakeFirst();
}
update(id: string, entity: Updateable<MoveHistory>) {
update(id: string, entity: Updateable<MoveTable>) {
return this.db
.updateTable('move_history')
.set(entity)

View File

@@ -2,9 +2,10 @@ import { Insertable, Kysely, Updateable } from 'kysely';
import { DateTime } from 'luxon';
import { InjectKysely } from 'nestjs-kysely';
import { columns } from 'src/database';
import { DB, Notifications } from 'src/db';
import { DummyValue, GenerateSql } from 'src/decorators';
import { NotificationSearchDto } from 'src/dtos/notification.dto';
import { DB } from 'src/schema';
import { NotificationTable } from 'src/schema/tables/notification.table';
export class NotificationRepository {
constructor(@InjectKysely() private db: Kysely<DB>) {}
@@ -53,7 +54,7 @@ export class NotificationRepository {
.execute();
}
create(notification: Insertable<Notifications>) {
create(notification: Insertable<NotificationTable>) {
return this.db
.insertInto('notifications')
.values(notification)
@@ -70,7 +71,7 @@ export class NotificationRepository {
.executeTakeFirst();
}
update(id: string, notification: Updateable<Notifications>) {
update(id: string, notification: Updateable<NotificationTable>) {
return this.db
.updateTable('notifications')
.set(notification)
@@ -80,7 +81,7 @@ export class NotificationRepository {
.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();
}

View File

@@ -3,8 +3,9 @@ import { ExpressionBuilder, Insertable, Kysely, NotNull, Updateable } from 'kyse
import { jsonObjectFrom } from 'kysely/helpers/postgres';
import { InjectKysely } from 'nestjs-kysely';
import { columns } from 'src/database';
import { DB, Partners } from 'src/db';
import { DummyValue, GenerateSql } from 'src/decorators';
import { DB } from 'src/schema';
import { PartnerTable } from 'src/schema/tables/partner.table';
export interface PartnerIds {
sharedById: string;
@@ -47,7 +48,7 @@ export class PartnerRepository {
.executeTakeFirst();
}
create(values: Insertable<Partners>) {
create(values: Insertable<PartnerTable>) {
return this.db
.insertInto('partners')
.values(values)
@@ -59,7 +60,7 @@ export class PartnerRepository {
}
@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
.updateTable('partners')
.set(values)

View File

@@ -2,9 +2,12 @@ import { Injectable } from '@nestjs/common';
import { ExpressionBuilder, Insertable, Kysely, Selectable, sql, Updateable } from 'kysely';
import { jsonObjectFrom } from 'kysely/helpers/postgres';
import { InjectKysely } from 'nestjs-kysely';
import { AssetFaces, DB, FaceSearch, Person } from 'src/db';
import { Chunked, ChunkedArray, DummyValue, GenerateSql } from 'src/decorators';
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 { paginationHelper, PaginationOptions } from 'src/utils/pagination';
@@ -57,7 +60,7 @@ export interface GetAllFacesOptions {
export type UnassignFacesOptions = DeleteFacesOptions;
export type SelectFaceOptions = (keyof Selectable<AssetFaces>)[];
export type SelectFaceOptions = (keyof Selectable<AssetFaceTable>)[];
const withPerson = (eb: ExpressionBuilder<DB, 'asset_faces'>) => {
return jsonObjectFrom(
@@ -378,11 +381,11 @@ export class PersonRepository {
.executeTakeFirstOrThrow();
}
create(person: Insertable<Person>) {
create(person: Insertable<PersonTable>) {
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) {
return [];
}
@@ -393,9 +396,9 @@ export class PersonRepository {
@GenerateSql({ params: [[], [], [{ faceId: DummyValue.UUID, embedding: DummyValue.VECTOR }]] })
async refreshFaces(
facesToAdd: (Insertable<AssetFaces> & { assetId: string })[],
facesToAdd: (Insertable<AssetFaceTable> & { assetId: string })[],
faceIdsToRemove: string[],
embeddingsToAdd?: Insertable<FaceSearch>[],
embeddingsToAdd?: Insertable<FaceSearchTable>[],
): Promise<void> {
let query = this.db;
if (facesToAdd.length > 0) {
@@ -415,7 +418,7 @@ export class PersonRepository {
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
.updateTable('person')
.set(person)
@@ -424,7 +427,7 @@ export class PersonRepository {
.executeTakeFirstOrThrow();
}
async updateAll(people: Insertable<Person>[]): Promise<void> {
async updateAll(people: Insertable<PersonTable>[]): Promise<void> {
if (people.length === 0) {
return;
}
@@ -496,7 +499,7 @@ export class PersonRepository {
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();
}

View File

@@ -2,11 +2,12 @@ import { Injectable } from '@nestjs/common';
import { Kysely, OrderByDirection, Selectable, sql } from 'kysely';
import { InjectKysely } from 'nestjs-kysely';
import { randomUUID } from 'node:crypto';
import { DB, Exif } from 'src/db';
import { DummyValue, GenerateSql } from 'src/decorators';
import { MapAsset } from 'src/dtos/asset-response.dto';
import { AssetStatus, AssetType, AssetVisibility, VectorIndex } from 'src/enum';
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 { paginationHelper } from 'src/utils/pagination';
import { isValidInteger } from 'src/validation';
@@ -385,7 +386,7 @@ export class SearchRepository {
.select((eb) =>
eb
.fn('to_jsonb', [eb.table('exif')])
.$castTo<Selectable<Exif>>()
.$castTo<Selectable<ExifTable>>()
.as('exifInfo'),
)
.orderBy('exif.city')

View File

@@ -4,8 +4,9 @@ import { jsonObjectFrom } from 'kysely/helpers/postgres';
import { DateTime } from 'luxon';
import { InjectKysely } from 'nestjs-kysely';
import { columns } from 'src/database';
import { DB, Sessions } from 'src/db';
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';
export type SessionSearchOptions = { updatedBefore: Date };
@@ -72,11 +73,11 @@ export class SessionRepository {
.execute();
}
create(dto: Insertable<Sessions>) {
create(dto: Insertable<SessionTable>) {
return this.db.insertInto('sessions').values(dto).returningAll().executeTakeFirstOrThrow();
}
update(id: string, dto: Updateable<Sessions>) {
update(id: string, dto: Updateable<SessionTable>) {
return this.db
.updateTable('sessions')
.set(dto)

View File

@@ -4,10 +4,11 @@ import { jsonObjectFrom } from 'kysely/helpers/postgres';
import _ from 'lodash';
import { InjectKysely } from 'nestjs-kysely';
import { Album, columns } from 'src/database';
import { DB, SharedLinks } from 'src/db';
import { DummyValue, GenerateSql } from 'src/decorators';
import { MapAsset } from 'src/dtos/asset-response.dto';
import { SharedLinkType } from 'src/enum';
import { DB } from 'src/schema';
import { SharedLinkTable } from 'src/schema/tables/shared-link.table';
export type SharedLinkSearchOptions = {
userId: string;
@@ -183,7 +184,7 @@ export class SharedLinkRepository {
.executeTakeFirst();
}
async create(entity: Insertable<SharedLinks> & { assetIds?: string[] }) {
async create(entity: Insertable<SharedLinkTable> & { assetIds?: string[] }) {
const { id } = await this.db
.insertInto('shared_links')
.values(_.omit(entity, 'assetIds'))
@@ -200,7 +201,7 @@ export class SharedLinkRepository {
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
.updateTable('shared_links')
.set(_.omit(entity, 'assets', 'album', 'assetIds'))

View File

@@ -3,8 +3,9 @@ import { ExpressionBuilder, Kysely, Updateable } from 'kysely';
import { jsonArrayFrom } from 'kysely/helpers/postgres';
import { InjectKysely } from 'nestjs-kysely';
import { columns } from 'src/database';
import { AssetStack, DB } from 'src/db';
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';
export interface StackSearch {
@@ -130,7 +131,7 @@ export class StackRepository {
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
.updateTable('asset_stack')
.set(entity)

View File

@@ -1,9 +1,10 @@
import { Injectable } from '@nestjs/common';
import { Insertable, Kysely } from 'kysely';
import { InjectKysely } from 'nestjs-kysely';
import { DB, SessionSyncCheckpoints } from 'src/db';
import { DummyValue, GenerateSql } from 'src/decorators';
import { SyncEntityType } from 'src/enum';
import { DB } from 'src/schema';
import { SessionSyncCheckpointTable } from 'src/schema/tables/sync-checkpoint.table';
@Injectable()
export class SyncCheckpointRepository {
@@ -18,7 +19,7 @@ export class SyncCheckpointRepository {
.execute();
}
upsertAll(items: Insertable<SessionSyncCheckpoints>[]) {
upsertAll(items: Insertable<SessionSyncCheckpointTable>[]) {
return this.db
.insertInto('session_sync_checkpoints')
.values(items)

View File

@@ -2,8 +2,8 @@ import { Injectable } from '@nestjs/common';
import { Kysely, SelectQueryBuilder, sql } from 'kysely';
import { InjectKysely } from 'nestjs-kysely';
import { columns } from 'src/database';
import { DB } from 'src/db';
import { DummyValue, GenerateSql } from 'src/decorators';
import { DB } from 'src/schema';
import { SyncAck } from 'src/types';
type AuditTables =

View File

@@ -2,11 +2,12 @@ import { Injectable } from '@nestjs/common';
import { Insertable, Kysely } from 'kysely';
import { InjectKysely } from 'nestjs-kysely';
import { readFile } from 'node:fs/promises';
import { DB, SystemMetadata as DbSystemMetadata } from 'src/db';
import { GenerateSql } from 'src/decorators';
import { DB } from 'src/schema';
import { SystemMetadataTable } from 'src/schema/tables/system-metadata.table';
import { SystemMetadata } from 'src/types';
type Upsert = Insertable<DbSystemMetadata>;
type Upsert = Insertable<SystemMetadataTable>;
@Injectable()
export class SystemMetadataRepository {

View File

@@ -2,9 +2,11 @@ import { Injectable } from '@nestjs/common';
import { Insertable, Kysely, sql, Updateable } from 'kysely';
import { InjectKysely } from 'nestjs-kysely';
import { columns } from 'src/database';
import { DB, TagAsset, Tags } from 'src/db';
import { Chunked, ChunkedSet, DummyValue, GenerateSql } from 'src/decorators';
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()
export class TagRepository {
@@ -72,12 +74,12 @@ export class TagRepository {
}
@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();
}
@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();
}
@@ -128,7 +130,7 @@ export class TagRepository {
@GenerateSql({ params: [[{ assetId: DummyValue.UUID, tagsIds: [DummyValue.UUID] }]] })
@Chunked()
upsertAssetIds(items: Insertable<TagAsset>[]) {
upsertAssetIds(items: Insertable<TagAssetTable>[]) {
if (items.length === 0) {
return Promise.resolve([]);
}

View File

@@ -1,8 +1,8 @@
import { Kysely } from 'kysely';
import { InjectKysely } from 'nestjs-kysely';
import { DB } from 'src/db';
import { DummyValue, GenerateSql } from 'src/decorators';
import { AssetStatus } from 'src/enum';
import { DB } from 'src/schema';
export class TrashRepository {
constructor(@InjectKysely() private db: Kysely<DB>) {}

View File

@@ -4,14 +4,15 @@ import { jsonArrayFrom } from 'kysely/helpers/postgres';
import { DateTime } from 'luxon';
import { InjectKysely } from 'nestjs-kysely';
import { columns } from 'src/database';
import { DB, UserMetadata as DbUserMetadata } from 'src/db';
import { DummyValue, GenerateSql } from 'src/decorators';
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 { UserMetadata, UserMetadataItem } from 'src/types';
import { asUuid } from 'src/utils/database';
type Upsert = Insertable<DbUserMetadata>;
type Upsert = Insertable<UserMetadataTable>;
export interface UserListFilter {
id?: string;

View File

@@ -1,8 +1,9 @@
import { Injectable } from '@nestjs/common';
import { Insertable, Kysely } from 'kysely';
import { InjectKysely } from 'nestjs-kysely';
import { DB, VersionHistory } from 'src/db';
import { GenerateSql } from 'src/decorators';
import { DB } from 'src/schema';
import { VersionHistoryTable } from 'src/schema/tables/version-history.table';
@Injectable()
export class VersionHistoryRepository {
@@ -18,7 +19,7 @@ export class VersionHistoryRepository {
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();
}
}

View File

@@ -1,8 +1,8 @@
import { Kysely } from 'kysely';
import { InjectKysely } from 'nestjs-kysely';
import { DB } from 'src/db';
import { DummyValue, GenerateSql } from 'src/decorators';
import { AssetVisibility } from 'src/enum';
import { DB } from 'src/schema';
import { asUuid, withExif } from 'src/utils/database';
export class ViewRepository {