From 25803813736e42fd8a8e492a2a2a203ac46237ea Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Thu, 6 Jun 2024 13:47:54 -0500 Subject: [PATCH] Create queries for lenses --- src/lens/index.ts | 47 +++++++++++++++++++++++++++++++++++++++++++ src/photo/cache.ts | 13 ++++++++++++ src/photo/db/index.ts | 9 +++++++++ src/photo/db/query.ts | 19 +++++++++++++++++ 4 files changed, 88 insertions(+) create mode 100644 src/lens/index.ts diff --git a/src/lens/index.ts b/src/lens/index.ts new file mode 100644 index 00000000..f5f25b6f --- /dev/null +++ b/src/lens/index.ts @@ -0,0 +1,47 @@ +import { Photo } from '@/photo'; +import { parameterize } from '@/utility/string'; + +const LENS_PLACEHOLDER: Lens = { make: 'Lens', model: 'Model' }; + +export type Lens = { + make: string + model: string +}; + +export interface LensProps { + params: Lens +} + +export interface PhotoLensProps { + params: Lens & { photoId: string } +} + +export type LensWithCount = { + lensKey: string + lens: Lens + count: number +} + +export type Lenses = LensWithCount[]; + +export const createLensKey = ({ make, model }: Lens) => + parameterize(`${make}-${model}`, true); + +export const getLensFromParams = ({ + make, + model, +}: { + make: string, + model: string, +}): Lens => ({ + make: parameterize(make, true), + model: parameterize(model, true), +}); + +export const lensFromPhoto = ( + photo: Photo | undefined, + fallback?: Lens, +): Lens => + photo?.lensMake && photo?.lensModel + ? { make: photo.lensMake, model: photo.lensModel } + : fallback ?? LENS_PLACEHOLDER; diff --git a/src/photo/cache.ts b/src/photo/cache.ts index 51792c04..07e3ce7c 100644 --- a/src/photo/cache.ts +++ b/src/photo/cache.ts @@ -15,6 +15,7 @@ import { getPhotosMostRecentUpdate, getPhotosMeta, getUniqueFocalLengths, + getUniqueLenses, } from '@/photo/db/query'; import { GetPhotosOptions } from './db'; import { parseCachedPhotoDates, parseCachedPhotosDates } from '@/photo'; @@ -30,6 +31,7 @@ import { PREFIX_TAG, pathForPhoto, } from '@/site/paths'; +import { createLensKey } from '@/lens'; // Table key const KEY_PHOTOS = 'photos'; @@ -37,6 +39,7 @@ const KEY_PHOTO = 'photo'; // Field keys const KEY_TAGS = 'tags'; const KEY_CAMERAS = 'cameras'; +const KEY_LENSES = 'lenses'; const KEY_FILM_SIMULATIONS = 'film-simulations'; const KEY_FOCAL_LENGTHS = 'focal-lengths'; // Type keys @@ -54,6 +57,10 @@ const getPhotosCacheKeyForOption = ( const value = options[option]; return value ? `${option}-${createCameraKey(value)}` : null; } + case 'lens': { + const value = options[option]; + return value ? `${option}-${createLensKey(value)}` : null; + } case 'takenBefore': case 'takenAfterInclusive': { const value = options[option]; @@ -192,6 +199,12 @@ export const getUniqueCamerasCached = [KEY_PHOTOS, KEY_CAMERAS] ); +export const getUniqueLensesCached = + unstable_cache( + getUniqueLenses, + [KEY_PHOTOS, KEY_LENSES] + ); + export const getUniqueFilmSimulationsCached = unstable_cache( getUniqueFilmSimulations, diff --git a/src/photo/db/index.ts b/src/photo/db/index.ts index 79697d6c..0ab0a847 100644 --- a/src/photo/db/index.ts +++ b/src/photo/db/index.ts @@ -1,4 +1,5 @@ import { Camera } from '@/camera'; +import { Lens } from '@/lens'; import { FilmSimulation } from '@/simulation'; import { PRIORITY_ORDER_ENABLED } from '@/site/config'; import { parameterize } from '@/utility/string'; @@ -13,6 +14,7 @@ export type GetPhotosOptions = { query?: string tag?: string camera?: Camera + lens?: Lens simulation?: FilmSimulation focal?: number takenBefore?: Date @@ -31,6 +33,7 @@ export const getWheresFromOptions = ( query, tag, camera, + lens, simulation, focal, } = options; @@ -71,6 +74,12 @@ export const getWheresFromOptions = ( wheresValues.push(parameterize(camera.make, true)); wheresValues.push(parameterize(camera.model, true)); } + if (lens) { + wheres.push(`LOWER(REPLACE(lens_make, ' ', '-'))=$${valuesIndex++}`); + wheres.push(`LOWER(REPLACE(lens_model, ' ', '-'))=$${valuesIndex++}`); + wheresValues.push(parameterize(lens.make, true)); + wheresValues.push(parameterize(lens.model, true)); + } if (simulation) { wheres.push(`film_simulation=$${valuesIndex++}`); wheresValues.push(simulation); diff --git a/src/photo/db/query.ts b/src/photo/db/query.ts index 9adfae8f..c2150c80 100644 --- a/src/photo/db/query.ts +++ b/src/photo/db/query.ts @@ -22,6 +22,7 @@ import { } from '.'; import { getWheresFromOptions } from '.'; import { FocalLengths } from '@/focal'; +import { Lenses, createLensKey } from '@/lens'; const createPhotosTable = () => sql` @@ -294,6 +295,24 @@ export const getUniqueCameras = async () => }))) , 'getUniqueCameras'); +export const getUniqueLenses = async () => + safelyQueryPhotos(() => sql` + SELECT DISTINCT lens_make||' '||lens_model as lens, + lens_make, lens_model, COUNT(*) + FROM photos + WHERE hidden IS NOT TRUE + AND trim(lens_make) <> '' + AND trim(lens_model) <> '' + GROUP BY lens_make, lens_model + ORDER BY lens ASC + `.then(({ rows }): Lenses => rows + .map(({ lens_make: make, lens_model: model, count }) => ({ + lensKey: createLensKey({ make, model }), + lens: { make, model }, + count: parseInt(count, 10), + }))) + , 'getUniqueCameras'); + export const getUniqueFilmSimulations = async () => safelyQueryPhotos(() => sql` SELECT DISTINCT film_simulation, COUNT(*)