Add full film simulation postgres queries
This commit is contained in:
parent
503ef6ca7c
commit
bf5bb1b83a
47
src/cache/index.ts
vendored
47
src/cache/index.ts
vendored
@ -13,12 +13,15 @@ import {
|
|||||||
getPhotosCameraDateRange,
|
getPhotosCameraDateRange,
|
||||||
getUniqueTagsHidden,
|
getUniqueTagsHidden,
|
||||||
getUniqueFilmSimulations,
|
getUniqueFilmSimulations,
|
||||||
|
getPhotosFilmSimulationDateRange,
|
||||||
|
getPhotosFilmSimulationCount,
|
||||||
} from '@/services/postgres';
|
} from '@/services/postgres';
|
||||||
import { parseCachedPhotosDates, parseCachedPhotoDates } from '@/photo';
|
import { parseCachedPhotosDates, parseCachedPhotoDates } from '@/photo';
|
||||||
import { getBlobPhotoUrls, getBlobUploadUrls } from '@/services/blob';
|
import { getBlobPhotoUrls, getBlobUploadUrls } from '@/services/blob';
|
||||||
import type { Session } from 'next-auth';
|
import type { Session } from 'next-auth';
|
||||||
import { Camera, createCameraKey } from '@/camera';
|
import { Camera, createCameraKey } from '@/camera';
|
||||||
import { PATHS_ADMIN, PATHS_TO_CACHE } from '@/site/paths';
|
import { PATHS_ADMIN, PATHS_TO_CACHE } from '@/site/paths';
|
||||||
|
import { FujifilmSimulation } from '@/vendors/fujifilm';
|
||||||
|
|
||||||
const KEY_PHOTOS = 'photos';
|
const KEY_PHOTOS = 'photos';
|
||||||
const KEY_PHOTOS_COUNT = `${KEY_PHOTOS}-count`;
|
const KEY_PHOTOS_COUNT = `${KEY_PHOTOS}-count`;
|
||||||
@ -27,8 +30,6 @@ const KEY_TAGS = 'tags';
|
|||||||
const KEY_CAMERAS = 'cameras';
|
const KEY_CAMERAS = 'cameras';
|
||||||
const KEY_FILM_SIMULATIONS = 'film-simulations';
|
const KEY_FILM_SIMULATIONS = 'film-simulations';
|
||||||
const KEY_BLOB = 'blob';
|
const KEY_BLOB = 'blob';
|
||||||
// Temporary key to clear caches on forked blogs
|
|
||||||
const KEY_NEW_QUERY = 'new-query';
|
|
||||||
|
|
||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
const getPhotosCacheKeyForOption = (
|
const getPhotosCacheKeyForOption = (
|
||||||
@ -39,8 +40,8 @@ const getPhotosCacheKeyForOption = (
|
|||||||
// Primitive keys
|
// Primitive keys
|
||||||
case 'sortBy':
|
case 'sortBy':
|
||||||
case 'limit':
|
case 'limit':
|
||||||
case 'offset':
|
|
||||||
case 'tag':
|
case 'tag':
|
||||||
|
case 'simulation':
|
||||||
case 'includeHidden': {
|
case 'includeHidden': {
|
||||||
const value = options[option];
|
const value = options[option];
|
||||||
return value ? `${option}-${value}` : null;
|
return value ? `${option}-${value}` : null;
|
||||||
@ -81,12 +82,18 @@ const getPhotoTagCountKey = (tag: string) =>
|
|||||||
const getPhotoCameraCountKey = (camera: Camera) =>
|
const getPhotoCameraCountKey = (camera: Camera) =>
|
||||||
`${KEY_PHOTOS_COUNT}-${KEY_CAMERAS}-${createCameraKey(camera)}`;
|
`${KEY_PHOTOS_COUNT}-${KEY_CAMERAS}-${createCameraKey(camera)}`;
|
||||||
|
|
||||||
|
const getPhotoFilmSimulationCountKey = (simulation: FujifilmSimulation) =>
|
||||||
|
`${KEY_PHOTOS_COUNT}-${KEY_FILM_SIMULATIONS}-${simulation}`;
|
||||||
|
|
||||||
const getPhotoTagDateRangeKey = (tag: string) =>
|
const getPhotoTagDateRangeKey = (tag: string) =>
|
||||||
`${KEY_PHOTOS_DATE_RANGE}-${KEY_TAGS}-${tag}`;
|
`${KEY_PHOTOS_DATE_RANGE}-${KEY_TAGS}-${tag}`;
|
||||||
|
|
||||||
const getPhotoCameraDateRangeKey = (camera: Camera) =>
|
const getPhotoCameraDateRangeKey = (camera: Camera) =>
|
||||||
`${KEY_PHOTOS_DATE_RANGE}-${KEY_CAMERAS}-${createCameraKey(camera)}`;
|
`${KEY_PHOTOS_DATE_RANGE}-${KEY_CAMERAS}-${createCameraKey(camera)}`;
|
||||||
|
|
||||||
|
const getPhotoFilmSimulationDateRangeKey = (simulation: FujifilmSimulation) =>
|
||||||
|
`${KEY_PHOTOS_DATE_RANGE}-${KEY_FILM_SIMULATIONS}-${simulation}`;
|
||||||
|
|
||||||
export const revalidatePhotosKey = () =>
|
export const revalidatePhotosKey = () =>
|
||||||
revalidateTag(KEY_PHOTOS);
|
revalidateTag(KEY_PHOTOS);
|
||||||
|
|
||||||
@ -96,6 +103,9 @@ export const revalidateTagsKey = () =>
|
|||||||
export const revalidateCamerasKey = () =>
|
export const revalidateCamerasKey = () =>
|
||||||
revalidateTag(KEY_CAMERAS);
|
revalidateTag(KEY_CAMERAS);
|
||||||
|
|
||||||
|
export const revalidateFilmSimulationsKey = () =>
|
||||||
|
revalidateTag(KEY_FILM_SIMULATIONS);
|
||||||
|
|
||||||
export const revalidateBlobKey = () =>
|
export const revalidateBlobKey = () =>
|
||||||
revalidateTag(KEY_BLOB);
|
revalidateTag(KEY_BLOB);
|
||||||
|
|
||||||
@ -108,6 +118,7 @@ export const revalidateAllKeys = () => {
|
|||||||
revalidatePhotosAndBlobKeys();
|
revalidatePhotosAndBlobKeys();
|
||||||
revalidateTagsKey();
|
revalidateTagsKey();
|
||||||
revalidateCamerasKey();
|
revalidateCamerasKey();
|
||||||
|
revalidateFilmSimulationsKey();
|
||||||
};
|
};
|
||||||
|
|
||||||
export const revalidateAllKeysAndPaths = () => {
|
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
|
// eslint-disable-next-line max-len
|
||||||
export const getPhotosTagDateRangeCached: typeof getPhotosTagDateRange = (...args) =>
|
export const getPhotosTagDateRangeCached: typeof getPhotosTagDateRange = (...args) =>
|
||||||
unstable_cache(
|
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) =>
|
export const getPhotoCached: typeof getPhoto = (...args) =>
|
||||||
unstable_cache(
|
unstable_cache(
|
||||||
() => getPhoto(...args),
|
() => getPhoto(...args),
|
||||||
@ -190,8 +219,8 @@ export const getPhotoCached: typeof getPhoto = (...args) =>
|
|||||||
export const getUniqueTagsCached: typeof getUniqueTags = (...args) =>
|
export const getUniqueTagsCached: typeof getUniqueTags = (...args) =>
|
||||||
unstable_cache(
|
unstable_cache(
|
||||||
() => getUniqueTags(...args),
|
() => getUniqueTags(...args),
|
||||||
[KEY_PHOTOS, KEY_TAGS, KEY_NEW_QUERY], {
|
[KEY_PHOTOS, KEY_TAGS], {
|
||||||
tags: [KEY_PHOTOS, KEY_TAGS, KEY_NEW_QUERY],
|
tags: [KEY_PHOTOS, KEY_TAGS],
|
||||||
}
|
}
|
||||||
)();
|
)();
|
||||||
|
|
||||||
@ -199,16 +228,16 @@ export const getUniqueTagsCached: typeof getUniqueTags = (...args) =>
|
|||||||
export const getUniqueTagsHiddenCached: typeof getUniqueTagsHidden = (...args) =>
|
export const getUniqueTagsHiddenCached: typeof getUniqueTagsHidden = (...args) =>
|
||||||
unstable_cache(
|
unstable_cache(
|
||||||
() => getUniqueTagsHidden(...args),
|
() => getUniqueTagsHidden(...args),
|
||||||
[KEY_PHOTOS, KEY_TAGS, KEY_NEW_QUERY], {
|
[KEY_PHOTOS, KEY_TAGS], {
|
||||||
tags: [KEY_PHOTOS, KEY_TAGS, KEY_NEW_QUERY],
|
tags: [KEY_PHOTOS, KEY_TAGS],
|
||||||
}
|
}
|
||||||
)();
|
)();
|
||||||
|
|
||||||
export const getUniqueCamerasCached: typeof getUniqueCameras = (...args) =>
|
export const getUniqueCamerasCached: typeof getUniqueCameras = (...args) =>
|
||||||
unstable_cache(
|
unstable_cache(
|
||||||
() => getUniqueCameras(...args),
|
() => getUniqueCameras(...args),
|
||||||
[KEY_PHOTOS, KEY_CAMERAS, KEY_NEW_QUERY], {
|
[KEY_PHOTOS, KEY_CAMERAS], {
|
||||||
tags: [KEY_PHOTOS, KEY_CAMERAS, KEY_NEW_QUERY],
|
tags: [KEY_PHOTOS, KEY_CAMERAS],
|
||||||
}
|
}
|
||||||
)();
|
)();
|
||||||
|
|
||||||
|
|||||||
@ -196,7 +196,6 @@ const sqlGetPhotosSortedByPriority = (
|
|||||||
|
|
||||||
const sqlGetPhotosByTag = (
|
const sqlGetPhotosByTag = (
|
||||||
limit = PHOTO_DEFAULT_LIMIT,
|
limit = PHOTO_DEFAULT_LIMIT,
|
||||||
offset = 0,
|
|
||||||
tag: string,
|
tag: string,
|
||||||
) =>
|
) =>
|
||||||
sql<PhotoDb>`
|
sql<PhotoDb>`
|
||||||
@ -204,7 +203,7 @@ const sqlGetPhotosByTag = (
|
|||||||
WHERE ${tag}=ANY(tags)
|
WHERE ${tag}=ANY(tags)
|
||||||
AND hidden IS NOT TRUE
|
AND hidden IS NOT TRUE
|
||||||
ORDER BY taken_at ASC
|
ORDER BY taken_at ASC
|
||||||
LIMIT ${limit} OFFSET ${offset}
|
LIMIT ${limit}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const sqlGetPhotosByCamera = async (
|
const sqlGetPhotosByCamera = async (
|
||||||
@ -220,6 +219,17 @@ const sqlGetPhotosByCamera = async (
|
|||||||
LIMIT ${limit}
|
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 = (
|
const sqlGetPhotosTakenAfterDateInclusive = (
|
||||||
takenAt: Date,
|
takenAt: Date,
|
||||||
limit?: number,
|
limit?: number,
|
||||||
@ -270,6 +280,14 @@ const sqlGetPhotosCameraCount = async (camera: Camera) => sql`
|
|||||||
hidden IS NOT TRUE
|
hidden IS NOT TRUE
|
||||||
`.then(({ rows }) => parseInt(rows[0].count, 10));
|
`.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`
|
const sqlGetPhotosTagDateRange = async (tag: string) => sql`
|
||||||
SELECT MIN(taken_at_naive) as start, MAX(taken_at_naive) as end
|
SELECT MIN(taken_at_naive) as start, MAX(taken_at_naive) as end
|
||||||
FROM photos
|
FROM photos
|
||||||
@ -286,6 +304,15 @@ const sqlGetPhotosCameraDateRange = async (camera: Camera) => sql`
|
|||||||
hidden IS NOT TRUE
|
hidden IS NOT TRUE
|
||||||
`.then(({ rows }) => rows[0] as PhotoDateRange);
|
`.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`
|
const sqlGetUniqueTags = async () => sql`
|
||||||
SELECT DISTINCT unnest(tags) as tag, COUNT(*)
|
SELECT DISTINCT unnest(tags) as tag, COUNT(*)
|
||||||
FROM photos
|
FROM photos
|
||||||
@ -334,9 +361,9 @@ const sqlGetUniqueFilmSimulations = async () => sql`
|
|||||||
export type GetPhotosOptions = {
|
export type GetPhotosOptions = {
|
||||||
sortBy?: 'createdAt' | 'takenAt' | 'priority'
|
sortBy?: 'createdAt' | 'takenAt' | 'priority'
|
||||||
limit?: number
|
limit?: number
|
||||||
offset?: number
|
|
||||||
tag?: string
|
tag?: string
|
||||||
camera?: Camera
|
camera?: Camera
|
||||||
|
simulation?: FujifilmSimulation
|
||||||
takenBefore?: Date
|
takenBefore?: Date
|
||||||
takenAfterInclusive?: Date
|
takenAfterInclusive?: Date
|
||||||
includeHidden?: boolean
|
includeHidden?: boolean
|
||||||
@ -375,31 +402,33 @@ export const getPhotos = async (options: GetPhotosOptions = {}) => {
|
|||||||
const {
|
const {
|
||||||
sortBy = 'takenAt',
|
sortBy = 'takenAt',
|
||||||
limit,
|
limit,
|
||||||
offset,
|
|
||||||
tag,
|
tag,
|
||||||
camera,
|
camera,
|
||||||
|
simulation,
|
||||||
takenBefore,
|
takenBefore,
|
||||||
takenAfterInclusive,
|
takenAfterInclusive,
|
||||||
includeHidden,
|
includeHidden,
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
let getPhotosSql = () => sqlGetPhotos(limit, offset);
|
let getPhotosSql = () => sqlGetPhotos(limit);
|
||||||
|
|
||||||
if (includeHidden) {
|
if (includeHidden) {
|
||||||
getPhotosSql = () => sqlGetPhotosIncludingHidden(limit, offset);
|
getPhotosSql = () => sqlGetPhotosIncludingHidden(limit);
|
||||||
} else if (takenBefore) {
|
} else if (takenBefore) {
|
||||||
getPhotosSql = () => sqlGetPhotosTakenBeforeDate(takenBefore, limit);
|
getPhotosSql = () => sqlGetPhotosTakenBeforeDate(takenBefore, limit);
|
||||||
} else if (takenAfterInclusive) {
|
} else if (takenAfterInclusive) {
|
||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
getPhotosSql = () => sqlGetPhotosTakenAfterDateInclusive(takenAfterInclusive, limit);
|
getPhotosSql = () => sqlGetPhotosTakenAfterDateInclusive(takenAfterInclusive, limit);
|
||||||
} else if (tag) {
|
} else if (tag) {
|
||||||
getPhotosSql = () => sqlGetPhotosByTag(limit, offset, tag);
|
getPhotosSql = () => sqlGetPhotosByTag(limit, tag);
|
||||||
} else if (camera) {
|
} else if (camera) {
|
||||||
getPhotosSql = () => sqlGetPhotosByCamera(limit, camera.make, camera.model);
|
getPhotosSql = () => sqlGetPhotosByCamera(limit, camera.make, camera.model);
|
||||||
|
} else if (simulation) {
|
||||||
|
getPhotosSql = () => sqlGetPhotosBySimulation(limit, simulation);
|
||||||
} else if (sortBy === 'createdAt') {
|
} else if (sortBy === 'createdAt') {
|
||||||
getPhotosSql = () => sqlGetPhotosSortedByCreatedAt(limit, offset);
|
getPhotosSql = () => sqlGetPhotosSortedByCreatedAt(limit);
|
||||||
} else if (sortBy === 'priority') {
|
} else if (sortBy === 'priority') {
|
||||||
getPhotosSql = () => sqlGetPhotosSortedByPriority(limit, offset);
|
getPhotosSql = () => sqlGetPhotosSortedByPriority(limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
return safelyQueryPhotos(getPhotosSql)
|
return safelyQueryPhotos(getPhotosSql)
|
||||||
@ -439,3 +468,8 @@ export const getPhotosCameraCount = (camera: Camera) =>
|
|||||||
// FILM SIMULATIONS
|
// FILM SIMULATIONS
|
||||||
export const getUniqueFilmSimulations = () =>
|
export const getUniqueFilmSimulations = () =>
|
||||||
safelyQueryPhotos(sqlGetUniqueFilmSimulations);
|
safelyQueryPhotos(sqlGetUniqueFilmSimulations);
|
||||||
|
export const getPhotosFilmSimulationDateRange =
|
||||||
|
(simulation: FujifilmSimulation) => safelyQueryPhotos(() =>
|
||||||
|
sqlGetPhotosFilmSimulationDateRange(simulation));
|
||||||
|
export const getPhotosFilmSimulationCount = (simulation: FujifilmSimulation) =>
|
||||||
|
safelyQueryPhotos(() => sqlGetPhotosFilmSimulationCount(simulation));
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user