Use nulls, make-sql

This commit is contained in:
Min Idzelis
2025-05-03 02:06:34 +00:00
parent 0ed2a2fd2e
commit aea2c9506d
19 changed files with 186 additions and 205 deletions

View File

@@ -72,7 +72,9 @@ class SqlGenerator {
await rm(this.options.targetDir, { force: true, recursive: true });
await mkdir(this.options.targetDir);
process.env.DB_HOSTNAME = 'localhost';
if (!process.env.DB_HOSTNAME) {
process.env.DB_HOSTNAME = 'localhost';
}
const { database, cls, otel } = new ConfigRepository().getEnv();
const moduleFixture = await Test.createTestingModule({

View File

@@ -183,7 +183,7 @@ export function mapAsset(entity: MapAsset, options: AssetMapOptions = {}): Asset
tags: entity.tags?.map((tag) => mapTag(tag)),
people: peopleWithFaces(entity.faces),
unassignedFaces: entity.faces?.filter((face) => !face.person).map((a) => mapFacesWithoutPerson(a)),
checksum: hexOrBufferToBase64(entity.checksum),
checksum: hexOrBufferToBase64(entity.checksum)!,
stack: withStack ? mapStack(entity) : undefined,
isOffline: entity.isOffline,
hasMetadata: true,

View File

@@ -104,12 +104,12 @@ export class TimeBucketAssetResponseDto implements TimeBucketAssets {
type: 'string',
},
{
type: 'number',
type: 'null',
},
],
},
})
thumbhash: (string | number)[] = [];
thumbhash: (string | null)[] = [];
@ApiProperty()
localDateTime: Date[] = [];
@@ -122,15 +122,27 @@ export class TimeBucketAssetResponseDto implements TimeBucketAssets {
type: 'string',
},
{
type: 'number',
type: 'null',
},
],
},
})
duration: (string | number)[] = [];
duration: (string | null)[] = [];
@ApiProperty({ type: [TimelineStackResponseDto] })
stack: (TimelineStackResponseDto | number)[] = [];
@ApiProperty({
type: 'array',
items: {
oneOf: [
{
type: 'TimelineStackResponseDto',
},
{
type: 'null',
},
],
},
})
stack: (TimelineStackResponseDto | null)[] = [];
@ApiProperty({
type: 'array',
@@ -140,12 +152,12 @@ export class TimeBucketAssetResponseDto implements TimeBucketAssets {
type: 'string',
},
{
type: 'number',
type: 'null',
},
],
},
})
projectionType: (string | number)[] = [];
projectionType: (string | null)[] = [];
@ApiProperty({
type: 'array',
@@ -155,12 +167,12 @@ export class TimeBucketAssetResponseDto implements TimeBucketAssets {
type: 'string',
},
{
type: 'number',
type: 'null',
},
],
},
})
livePhotoVideoId: (string | number)[] = [];
livePhotoVideoId: (string | null)[] = [];
@ApiProperty()
description: TimelineAssetDescriptionDto[] = [];

View File

@@ -255,8 +255,23 @@ order by
-- AssetRepository.getTimeBucket
select
"assets".*,
to_json("exif") as "exifInfo",
"assets"."id" as "id",
"assets"."ownerId",
"assets"."status",
"deletedAt",
"type",
"duration",
"isFavorite",
"isArchived",
"thumbhash",
"localDateTime",
"livePhotoVideoId",
"exif"."exifImageHeight" as "height",
"exifImageWidth" as "width",
"exif"."orientation",
"exif"."projectionType",
"exif"."city" as "city",
"exif"."country" as "country",
to_json("stacked_assets") as "stack"
from
"assets"

View File

@@ -142,7 +142,7 @@ export class SyncService extends BaseService {
updateId,
data: {
...data,
checksum: hexOrBufferToBase64(checksum),
checksum: hexOrBufferToBase64(checksum)!,
thumbhash: thumbhash ? hexOrBufferToBase64(thumbhash) : null,
},
}),
@@ -172,7 +172,7 @@ export class SyncService extends BaseService {
updateId,
data: {
...data,
checksum: hexOrBufferToBase64(checksum),
checksum: hexOrBufferToBase64(checksum)!,
thumbhash: thumbhash ? hexOrBufferToBase64(thumbhash) : null,
},
}),

View File

@@ -75,12 +75,12 @@ export class TimelineService extends BaseService {
bucketAssets.isArchived.push(item.isArchived ? 1 : 0);
bucketAssets.isFavorite.push(item.isFavorite ? 1 : 0);
bucketAssets.isTrashed.push(item.deletedAt === null ? 0 : 1);
bucketAssets.thumbhash.push(item.thumbhash ? hexOrBufferToBase64(item.thumbhash) : 0);
bucketAssets.thumbhash.push(hexOrBufferToBase64(item.thumbhash));
bucketAssets.localDateTime.push(item.localDateTime);
bucketAssets.stack.push(this.mapStack(item.stack) || 0);
bucketAssets.duration.push(item.duration || 0);
bucketAssets.projectionType.push(item.projectionType || 0);
bucketAssets.livePhotoVideoId.push(item.livePhotoVideoId || 0);
bucketAssets.stack.push(this.mapStack(item.stack));
bucketAssets.duration.push(item.duration);
bucketAssets.projectionType.push(item.projectionType);
bucketAssets.livePhotoVideoId.push(item.livePhotoVideoId);
bucketAssets.isImage.push(item.type === AssetType.IMAGE ? 1 : 0);
bucketAssets.isVideo.push(item.type === AssetType.VIDEO ? 1 : 0);
bucketAssets.description.push({
@@ -97,7 +97,7 @@ export class TimelineService extends BaseService {
mapStack(entity?: Stack | null) {
if (!entity) {
return;
return null;
}
return {

View File

@@ -18,11 +18,11 @@ export type TimeBucketAssets = {
isTrashed: number[];
isVideo: number[];
isImage: number[];
thumbhash: (string | number)[];
thumbhash: (string | null)[];
localDateTime: Date[];
stack: (TimelineStack | number)[];
duration: (string | number)[];
projectionType: (string | number)[];
livePhotoVideoId: (string | number)[];
stack: (TimelineStack | null)[];
duration: (string | null)[];
projectionType: (string | null)[];
livePhotoVideoId: (string | null)[];
description: AssetDescription[];
};

View File

@@ -24,7 +24,10 @@ export function asHumanReadable(bytes: number, precision = 1): string {
}
// if an asset is jsonified in the DB before being returned, its buffer fields will be hex-encoded strings
export const hexOrBufferToBase64 = (encoded: string | Buffer) => {
export const hexOrBufferToBase64 = (encoded: string | Buffer | null) => {
if (!encoded) {
return null;
}
if (typeof encoded === 'string') {
return Buffer.from(encoded.slice(2), 'hex').toString('base64');
}