Add full film simulation postgres queries

This commit is contained in:
Sam Becker 2023-11-05 20:37:00 -06:00
parent 503ef6ca7c
commit bf5bb1b83a
2 changed files with 81 additions and 18 deletions

47
src/cache/index.ts vendored
View File

@ -13,12 +13,15 @@ import {
getPhotosCameraDateRange,
getUniqueTagsHidden,
getUniqueFilmSimulations,
getPhotosFilmSimulationDateRange,
getPhotosFilmSimulationCount,
} from '@/services/postgres';
import { parseCachedPhotosDates, parseCachedPhotoDates } from '@/photo';
import { getBlobPhotoUrls, getBlobUploadUrls } from '@/services/blob';
import type { Session } from 'next-auth';
import { Camera, createCameraKey } from '@/camera';
import { PATHS_ADMIN, PATHS_TO_CACHE } from '@/site/paths';
import { FujifilmSimulation } from '@/vendors/fujifilm';
const KEY_PHOTOS = 'photos';
const KEY_PHOTOS_COUNT = `${KEY_PHOTOS}-count`;
@ -27,8 +30,6 @@ const KEY_TAGS = 'tags';
const KEY_CAMERAS = 'cameras';
const KEY_FILM_SIMULATIONS = 'film-simulations';
const KEY_BLOB = 'blob';
// Temporary key to clear caches on forked blogs
const KEY_NEW_QUERY = 'new-query';
// eslint-disable-next-line max-len
const getPhotosCacheKeyForOption = (
@ -39,8 +40,8 @@ const getPhotosCacheKeyForOption = (
// Primitive keys
case 'sortBy':
case 'limit':
case 'offset':
case 'tag':
case 'simulation':
case 'includeHidden': {
const value = options[option];
return value ? `${option}-${value}` : null;
@ -81,12 +82,18 @@ const getPhotoTagCountKey = (tag: string) =>
const getPhotoCameraCountKey = (camera: Camera) =>
`${KEY_PHOTOS_COUNT}-${KEY_CAMERAS}-${createCameraKey(camera)}`;
const getPhotoFilmSimulationCountKey = (simulation: FujifilmSimulation) =>
`${KEY_PHOTOS_COUNT}-${KEY_FILM_SIMULATIONS}-${simulation}`;
const getPhotoTagDateRangeKey = (tag: string) =>
`${KEY_PHOTOS_DATE_RANGE}-${KEY_TAGS}-${tag}`;
const getPhotoCameraDateRangeKey = (camera: Camera) =>
`${KEY_PHOTOS_DATE_RANGE}-${KEY_CAMERAS}-${createCameraKey(camera)}`;
const getPhotoFilmSimulationDateRangeKey = (simulation: FujifilmSimulation) =>
`${KEY_PHOTOS_DATE_RANGE}-${KEY_FILM_SIMULATIONS}-${simulation}`;
export const revalidatePhotosKey = () =>
revalidateTag(KEY_PHOTOS);
@ -96,6 +103,9 @@ export const revalidateTagsKey = () =>
export const revalidateCamerasKey = () =>
revalidateTag(KEY_CAMERAS);
export const revalidateFilmSimulationsKey = () =>
revalidateTag(KEY_FILM_SIMULATIONS);
export const revalidateBlobKey = () =>
revalidateTag(KEY_BLOB);
@ -108,6 +118,7 @@ export const revalidateAllKeys = () => {
revalidatePhotosAndBlobKeys();
revalidateTagsKey();
revalidateCamerasKey();
revalidateFilmSimulationsKey();
};
export const revalidateAllKeysAndPaths = () => {
@ -161,6 +172,15 @@ export const getPhotosCameraCountCached: typeof getPhotosCameraCount = (...args)
}
)();
// eslint-disable-next-line max-len
export const getPhotosFilmSimulationCountCached: typeof getPhotosFilmSimulationCount = (...args) =>
unstable_cache(
() => getPhotosFilmSimulationCount(...args),
[KEY_PHOTOS, getPhotoFilmSimulationCountKey(...args)], {
tags: [KEY_PHOTOS, getPhotoFilmSimulationCountKey(...args)],
}
)();
// eslint-disable-next-line max-len
export const getPhotosTagDateRangeCached: typeof getPhotosTagDateRange = (...args) =>
unstable_cache(
@ -179,6 +199,15 @@ export const getPhotosCameraDateRangeCached: typeof getPhotosCameraDateRange = (
}
)();
// eslint-disable-next-line max-len
export const getPhotosFilmSimulationDateRangeCached: typeof getPhotosFilmSimulationDateRange = (...args) =>
unstable_cache(
() => getPhotosFilmSimulationDateRange(...args),
[KEY_PHOTOS, getPhotoFilmSimulationDateRangeKey(...args)], {
tags: [KEY_PHOTOS, getPhotoFilmSimulationDateRangeKey(...args)],
}
)();
export const getPhotoCached: typeof getPhoto = (...args) =>
unstable_cache(
() => getPhoto(...args),
@ -190,8 +219,8 @@ export const getPhotoCached: typeof getPhoto = (...args) =>
export const getUniqueTagsCached: typeof getUniqueTags = (...args) =>
unstable_cache(
() => getUniqueTags(...args),
[KEY_PHOTOS, KEY_TAGS, KEY_NEW_QUERY], {
tags: [KEY_PHOTOS, KEY_TAGS, KEY_NEW_QUERY],
[KEY_PHOTOS, KEY_TAGS], {
tags: [KEY_PHOTOS, KEY_TAGS],
}
)();
@ -199,16 +228,16 @@ export const getUniqueTagsCached: typeof getUniqueTags = (...args) =>
export const getUniqueTagsHiddenCached: typeof getUniqueTagsHidden = (...args) =>
unstable_cache(
() => getUniqueTagsHidden(...args),
[KEY_PHOTOS, KEY_TAGS, KEY_NEW_QUERY], {
tags: [KEY_PHOTOS, KEY_TAGS, KEY_NEW_QUERY],
[KEY_PHOTOS, KEY_TAGS], {
tags: [KEY_PHOTOS, KEY_TAGS],
}
)();
export const getUniqueCamerasCached: typeof getUniqueCameras = (...args) =>
unstable_cache(
() => getUniqueCameras(...args),
[KEY_PHOTOS, KEY_CAMERAS, KEY_NEW_QUERY], {
tags: [KEY_PHOTOS, KEY_CAMERAS, KEY_NEW_QUERY],
[KEY_PHOTOS, KEY_CAMERAS], {
tags: [KEY_PHOTOS, KEY_CAMERAS],
}
)();

View File

@ -196,7 +196,6 @@ const sqlGetPhotosSortedByPriority = (
const sqlGetPhotosByTag = (
limit = PHOTO_DEFAULT_LIMIT,
offset = 0,
tag: string,
) =>
sql<PhotoDb>`
@ -204,7 +203,7 @@ const sqlGetPhotosByTag = (
WHERE ${tag}=ANY(tags)
AND hidden IS NOT TRUE
ORDER BY taken_at ASC
LIMIT ${limit} OFFSET ${offset}
LIMIT ${limit}
`;
const sqlGetPhotosByCamera = async (
@ -220,6 +219,17 @@ const sqlGetPhotosByCamera = async (
LIMIT ${limit}
`;
const sqlGetPhotosBySimulation = async (
limit = PHOTO_DEFAULT_LIMIT,
simulation: FujifilmSimulation,
) => sql<PhotoDb>`
SELECT * FROM photos
WHERE film_simulation=${simulation}
AND hidden IS NOT TRUE
ORDER BY taken_at ASC
LIMIT ${limit}
`;
const sqlGetPhotosTakenAfterDateInclusive = (
takenAt: Date,
limit?: number,
@ -270,6 +280,14 @@ const sqlGetPhotosCameraCount = async (camera: Camera) => sql`
hidden IS NOT TRUE
`.then(({ rows }) => parseInt(rows[0].count, 10));
const sqlGetPhotosFilmSimulationCount = async (
simulation: FujifilmSimulation,
) => sql`
SELECT COUNT(*) FROM photos
WHERE film_simulation=${simulation} AND
hidden IS NOT TRUE
`.then(({ rows }) => parseInt(rows[0].count, 10));
const sqlGetPhotosTagDateRange = async (tag: string) => sql`
SELECT MIN(taken_at_naive) as start, MAX(taken_at_naive) as end
FROM photos
@ -286,6 +304,15 @@ const sqlGetPhotosCameraDateRange = async (camera: Camera) => sql`
hidden IS NOT TRUE
`.then(({ rows }) => rows[0] as PhotoDateRange);
const sqlGetPhotosFilmSimulationDateRange = async (
simulation: FujifilmSimulation,
) => sql`
SELECT MIN(taken_at_naive) as start, MAX(taken_at_naive) as end
FROM photos
WHERE film_simulation=${simulation} AND
hidden IS NOT TRUE
`.then(({ rows }) => rows[0] as PhotoDateRange);
const sqlGetUniqueTags = async () => sql`
SELECT DISTINCT unnest(tags) as tag, COUNT(*)
FROM photos
@ -334,9 +361,9 @@ const sqlGetUniqueFilmSimulations = async () => sql`
export type GetPhotosOptions = {
sortBy?: 'createdAt' | 'takenAt' | 'priority'
limit?: number
offset?: number
tag?: string
camera?: Camera
simulation?: FujifilmSimulation
takenBefore?: Date
takenAfterInclusive?: Date
includeHidden?: boolean
@ -375,31 +402,33 @@ export const getPhotos = async (options: GetPhotosOptions = {}) => {
const {
sortBy = 'takenAt',
limit,
offset,
tag,
camera,
simulation,
takenBefore,
takenAfterInclusive,
includeHidden,
} = options;
let getPhotosSql = () => sqlGetPhotos(limit, offset);
let getPhotosSql = () => sqlGetPhotos(limit);
if (includeHidden) {
getPhotosSql = () => sqlGetPhotosIncludingHidden(limit, offset);
getPhotosSql = () => sqlGetPhotosIncludingHidden(limit);
} else if (takenBefore) {
getPhotosSql = () => sqlGetPhotosTakenBeforeDate(takenBefore, limit);
} else if (takenAfterInclusive) {
// eslint-disable-next-line max-len
getPhotosSql = () => sqlGetPhotosTakenAfterDateInclusive(takenAfterInclusive, limit);
} else if (tag) {
getPhotosSql = () => sqlGetPhotosByTag(limit, offset, tag);
getPhotosSql = () => sqlGetPhotosByTag(limit, tag);
} else if (camera) {
getPhotosSql = () => sqlGetPhotosByCamera(limit, camera.make, camera.model);
} else if (simulation) {
getPhotosSql = () => sqlGetPhotosBySimulation(limit, simulation);
} else if (sortBy === 'createdAt') {
getPhotosSql = () => sqlGetPhotosSortedByCreatedAt(limit, offset);
getPhotosSql = () => sqlGetPhotosSortedByCreatedAt(limit);
} else if (sortBy === 'priority') {
getPhotosSql = () => sqlGetPhotosSortedByPriority(limit, offset);
getPhotosSql = () => sqlGetPhotosSortedByPriority(limit);
}
return safelyQueryPhotos(getPhotosSql)
@ -439,3 +468,8 @@ export const getPhotosCameraCount = (camera: Camera) =>
// FILM SIMULATIONS
export const getUniqueFilmSimulations = () =>
safelyQueryPhotos(sqlGetUniqueFilmSimulations);
export const getPhotosFilmSimulationDateRange =
(simulation: FujifilmSimulation) => safelyQueryPhotos(() =>
sqlGetPhotosFilmSimulationDateRange(simulation));
export const getPhotosFilmSimulationCount = (simulation: FujifilmSimulation) =>
safelyQueryPhotos(() => sqlGetPhotosFilmSimulationCount(simulation));