From 2ec32cac12bf6f9b1f796963cd25eb746439da16 Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Fri, 15 Mar 2024 20:40:06 -0500 Subject: [PATCH] Add caption, description fields to Photo --- src/photo/form/index.ts | 2 ++ src/photo/index.ts | 2 ++ src/services/vercel-postgres.ts | 54 ++++++++++++++++++++++++--------- 3 files changed, 44 insertions(+), 14 deletions(-) diff --git a/src/photo/form/index.ts b/src/photo/form/index.ts index c1404a4a..5979828b 100644 --- a/src/photo/form/index.ts +++ b/src/photo/form/index.ts @@ -54,6 +54,8 @@ const FORM_METADATA = ( tagOptions?: AnnotatedTag[] ): Record => ({ title: { label: 'title', capitalize: true }, + caption: { label: 'caption', capitalize: true }, + description: { label: 'description', capitalize: true, hide: true}, tags: { label: 'tags', tagOptions, diff --git a/src/photo/index.ts b/src/photo/index.ts index 05608c81..cb4a003a 100644 --- a/src/photo/index.ts +++ b/src/photo/index.ts @@ -47,6 +47,8 @@ export interface PhotoDbInsert extends PhotoExif { extension: string blurData?: string title?: string + caption?: string + description?: string tags?: string[] locationName?: string priorityOrder?: number diff --git a/src/services/vercel-postgres.ts b/src/services/vercel-postgres.ts index 7cc7cc2b..00e41984 100644 --- a/src/services/vercel-postgres.ts +++ b/src/services/vercel-postgres.ts @@ -28,6 +28,8 @@ const sqlCreatePhotosTable = () => aspect_ratio REAL DEFAULT 1.5, blur_data TEXT, title VARCHAR(255), + caption TEXT, + description TEXT, tags VARCHAR(255)[], make VARCHAR(255), model VARCHAR(255), @@ -50,9 +52,18 @@ const sqlCreatePhotosTable = () => ) `; +// MIGRATION 01 +const MIGRATION_FIELDS_01 = ['caption', 'description']; +const sqlRunMigration01 = () => + sql` + ALTER TABLE photos + ADD COLUMN caption TEXT, + ADD COLUMN description TEXT + `; + // Must provide id as 8-character nanoid -export const sqlInsertPhoto = (photo: PhotoDbInsert) => { - return sql` +export const sqlInsertPhoto = (photo: PhotoDbInsert) => + safelyQueryPhotos(() => sql` INSERT INTO photos ( id, url, @@ -60,6 +71,8 @@ export const sqlInsertPhoto = (photo: PhotoDbInsert) => { aspect_ratio, blur_data, title, + caption, + description, tags, make, model, @@ -85,6 +98,8 @@ export const sqlInsertPhoto = (photo: PhotoDbInsert) => { ${photo.aspectRatio}, ${photo.blurData}, ${photo.title}, + ${photo.caption}, + ${photo.description}, ${convertArrayToPostgresString(photo.tags)}, ${photo.make}, ${photo.model}, @@ -103,17 +118,18 @@ export const sqlInsertPhoto = (photo: PhotoDbInsert) => { ${photo.takenAt}, ${photo.takenAtNaive} ) - `; -}; + `); export const sqlUpdatePhoto = (photo: PhotoDbInsert) => - sql` + safelyQueryPhotos(() => sql` UPDATE photos SET url=${photo.url}, extension=${photo.extension}, aspect_ratio=${photo.aspectRatio}, blur_data=${photo.blurData}, title=${photo.title}, + caption=${photo.caption}, + description=${photo.description}, tags=${convertArrayToPostgresString(photo.tags)}, make=${photo.make}, model=${photo.model}, @@ -133,27 +149,29 @@ export const sqlUpdatePhoto = (photo: PhotoDbInsert) => taken_at_naive=${photo.takenAtNaive}, updated_at=${(new Date()).toISOString()} WHERE id=${photo.id} - `; + `); export const sqlDeletePhotoTagGlobally = (tag: string) => - sql` + safelyQueryPhotos(() => sql` UPDATE photos SET tags=ARRAY_REMOVE(tags, ${tag}) WHERE ${tag}=ANY(tags) - `; + `); export const sqlRenamePhotoTagGlobally = (tag: string, updatedTag: string) => - sql` + safelyQueryPhotos(() => sql` UPDATE photos SET tags=ARRAY_REPLACE(tags, ${tag}, ${updatedTag}) WHERE ${tag}=ANY(tags) - `; + `); export const sqlDeletePhoto = (id: string) => - sql`DELETE FROM photos WHERE id=${id}`; + safelyQueryPhotos(() => sql`DELETE FROM photos WHERE id=${id}`); const sqlGetPhoto = (id: string) => - sql`SELECT * FROM photos WHERE id=${id} LIMIT 1`; + safelyQueryPhotos(() => + sql`SELECT * FROM photos WHERE id=${id} LIMIT 1` + ); const sqlGetPhotosCount = async () => sql` SELECT COUNT(*) FROM photos @@ -291,8 +309,16 @@ const safelyQueryPhotos = async (callback: () => Promise): Promise => { try { result = await callback(); } catch (e: any) { - if (/relation "photos" does not exist/i.test(e.message)) { - console.log('Creating table "photos" because it did not exist'); + if (MIGRATION_FIELDS_01.some(field => new RegExp( + `column "${field}" of relation "photos" does not exist`, + 'i', + ).test(e.message))) { + console.log('Running migration 01 ...'); + await sqlRunMigration01(); + result = await callback(); + } else if (/relation "photos" does not exist/i.test(e.message)) { + // If the table does not exist, create it + console.log('Creating photos table ...'); await sqlCreatePhotosTable(); result = await callback(); } else if (/endpoint is in transition/i.test(e.message)) {