Simplify tag sql queries
This commit is contained in:
parent
ee008d2861
commit
448c4301de
@ -1,6 +1,6 @@
|
||||
import AdminChildPage from '@/components/AdminChildPage';
|
||||
import { redirect } from 'next/navigation';
|
||||
import { getPhotosCached, getPhotosTagCountCached } from '@/photo/cache';
|
||||
import { getPhotosCached } from '@/photo/cache';
|
||||
import TagForm from '@/tag/TagForm';
|
||||
import { PATH_ADMIN, PATH_ADMIN_TAGS, pathForTag } from '@/site/paths';
|
||||
import PhotoTag from '@/tag/PhotoTag';
|
||||
@ -8,6 +8,7 @@ import { photoLabelForCount } from '@/photo';
|
||||
import PhotoLightbox from '@/photo/PhotoLightbox';
|
||||
import FavsTag from '@/tag/FavsTag';
|
||||
import { isTagFavs } from '@/tag';
|
||||
import { getPhotosTagMeta } from '@/services/vercel-postgres';
|
||||
|
||||
const MAX_PHOTO_TO_SHOW = 6;
|
||||
|
||||
@ -21,10 +22,10 @@ export default async function PhotoPageEdit({
|
||||
const tag = decodeURIComponent(tagFromParams);
|
||||
|
||||
const [
|
||||
count,
|
||||
{ count },
|
||||
photos,
|
||||
] = await Promise.all([
|
||||
getPhotosTagCountCached(tag),
|
||||
getPhotosTagMeta(tag),
|
||||
getPhotosCached({ tag, limit: MAX_PHOTO_TO_SHOW }),
|
||||
]);
|
||||
|
||||
|
||||
@ -58,8 +58,7 @@ export default async function PhotoTagPage({
|
||||
|
||||
const [
|
||||
photos,
|
||||
count,
|
||||
dateRange,
|
||||
{ count, dateRange },
|
||||
] = await getPhotosTagDataCached({ tag });
|
||||
|
||||
return <>
|
||||
|
||||
@ -19,8 +19,7 @@ export async function generateMetadata({
|
||||
|
||||
const [
|
||||
photos,
|
||||
count,
|
||||
dateRange,
|
||||
{ count, dateRange },
|
||||
] = await getPhotosTagDataCached({
|
||||
tag,
|
||||
limit: GRID_THUMBNAILS_TO_SHOW_MAX,
|
||||
|
||||
@ -10,14 +10,14 @@ import { useFormState } from 'react-dom';
|
||||
import { areSimpleObjectsEqual } from '@/utility/object';
|
||||
import IconGrSync from '@/site/IconGrSync';
|
||||
import { getExifDataAction } from './actions';
|
||||
import { Tags } from '@/tag';
|
||||
import { TagsWithMeta } from '@/tag';
|
||||
|
||||
export default function PhotoEditPageClient({
|
||||
photo,
|
||||
uniqueTags,
|
||||
}: {
|
||||
photo: Photo
|
||||
uniqueTags?: Tags
|
||||
uniqueTags?: TagsWithMeta
|
||||
}) {
|
||||
const seedExifData = { url: photo.url };
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ import PhotoTag from '@/tag/PhotoTag';
|
||||
import { FaTag } from 'react-icons/fa';
|
||||
import { IoMdCamera } from 'react-icons/io';
|
||||
import { PhotoDateRange, dateRangeForPhotos, photoQuantityText } from '.';
|
||||
import { TAG_FAVS, Tags } from '@/tag';
|
||||
import { TAG_FAVS, TagsWithMeta } from '@/tag';
|
||||
import PhotoFilmSimulation from '@/simulation/PhotoFilmSimulation';
|
||||
import PhotoFilmSimulationIcon from '@/simulation/PhotoFilmSimulationIcon';
|
||||
import { FilmSimulations, sortFilmSimulationsWithCount } from '@/simulation';
|
||||
@ -18,7 +18,7 @@ export default function PhotoGridSidebar({
|
||||
photosCount,
|
||||
photosDateRange,
|
||||
}: {
|
||||
tags: Tags
|
||||
tags: TagsWithMeta
|
||||
cameras: Cameras
|
||||
simulations: FilmSimulations
|
||||
photosCount: number
|
||||
|
||||
@ -11,10 +11,9 @@ import {
|
||||
getPhotosCount,
|
||||
getPhotosCameraCount,
|
||||
getPhotosCountIncludingHidden,
|
||||
getPhotosTagCount,
|
||||
getUniqueCameras,
|
||||
getUniqueTags,
|
||||
getPhotosTagDateRange,
|
||||
getPhotosTagMeta,
|
||||
getPhotosCameraDateRange,
|
||||
getUniqueTagsHidden,
|
||||
getUniqueFilmSimulations,
|
||||
@ -162,12 +161,6 @@ export const getPhotosCountIncludingHiddenCached =
|
||||
[KEY_PHOTOS, KEY_COUNT, KEY_HIDDEN],
|
||||
);
|
||||
|
||||
export const getPhotosTagCountCached =
|
||||
unstable_cache(
|
||||
getPhotosTagCount,
|
||||
[KEY_PHOTOS, KEY_TAGS],
|
||||
);
|
||||
|
||||
export const getPhotosCameraCountCached = (
|
||||
...args: Parameters<typeof getPhotosCameraCount>
|
||||
) =>
|
||||
@ -182,9 +175,9 @@ export const getPhotosFilmSimulationCountCached =
|
||||
[KEY_PHOTOS, KEY_FILM_SIMULATIONS, KEY_COUNT],
|
||||
);
|
||||
|
||||
export const getPhotosTagDateRangeCached =
|
||||
export const getPhotosTagMetaCached =
|
||||
unstable_cache(
|
||||
getPhotosTagDateRange,
|
||||
getPhotosTagMeta,
|
||||
[KEY_PHOTOS, KEY_TAGS, KEY_DATE_RANGE],
|
||||
);
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@ import { toastSuccess, toastWarning } from '@/toast';
|
||||
import { getDimensionsFromSize } from '@/utility/size';
|
||||
import ImageBlurFallback from '@/components/ImageBlurFallback';
|
||||
import { BLUR_ENABLED } from '@/site/config';
|
||||
import { Tags, sortTagsObjectWithoutFavs } from '@/tag';
|
||||
import { TagsWithMeta, sortTagsObjectWithoutFavs } from '@/tag';
|
||||
import { formatCount, formatCountDescriptive } from '@/utility/string';
|
||||
|
||||
const THUMBNAIL_SIZE = 300;
|
||||
@ -38,7 +38,7 @@ export default function PhotoForm({
|
||||
initialPhotoForm: Partial<PhotoFormData>
|
||||
updatedExifData?: Partial<PhotoFormData>
|
||||
type?: 'create' | 'edit'
|
||||
uniqueTags?: Tags
|
||||
uniqueTags?: TagsWithMeta
|
||||
debugBlur?: boolean
|
||||
}) {
|
||||
const [formData, setFormData] =
|
||||
|
||||
@ -9,7 +9,7 @@ import {
|
||||
} from '@/photo';
|
||||
import { Camera, Cameras, createCameraKey } from '@/camera';
|
||||
import { parameterize } from '@/utility/string';
|
||||
import { Tags } from '@/tag';
|
||||
import { TagsWithMeta } from '@/tag';
|
||||
import { FilmSimulation, FilmSimulations } from '@/simulation';
|
||||
import { PRIORITY_ORDER_ENABLED } from '@/site/config';
|
||||
import { screenForPPR } from '@/utility/ppr';
|
||||
@ -165,12 +165,6 @@ const sqlGetPhotosCountIncludingHidden = async () => sql`
|
||||
SELECT COUNT(*) FROM photos
|
||||
`.then(({ rows }) => parseInt(rows[0].count, 10));
|
||||
|
||||
const sqlGetPhotosTagCount = async (tag: string) => sql`
|
||||
SELECT COUNT(*) FROM photos
|
||||
WHERE ${tag}=ANY(tags) AND
|
||||
hidden IS NOT TRUE
|
||||
`.then(({ rows }) => parseInt(rows[0].count, 10));
|
||||
|
||||
const sqlGetPhotosCameraCount = async (camera: Camera) => sql`
|
||||
SELECT COUNT(*) FROM photos
|
||||
WHERE
|
||||
@ -195,14 +189,17 @@ const sqlGetPhotosDateRange = async () => sql`
|
||||
? rows[0] as PhotoDateRange
|
||||
: undefined);
|
||||
|
||||
const sqlGetPhotosTagDateRange = async (tag: string) => sql`
|
||||
SELECT MIN(taken_at_naive) as start, MAX(taken_at_naive) as end
|
||||
const sqlGetPhotosTagMeta = async (tag: string) => sql`
|
||||
SELECT COUNT(*), MIN(taken_at_naive) as start, MAX(taken_at_naive) as end
|
||||
FROM photos
|
||||
WHERE ${tag}=ANY(tags) AND
|
||||
hidden IS NOT TRUE
|
||||
`.then(({ rows }) => rows[0]?.start && rows[0]?.end
|
||||
? rows[0] as PhotoDateRange
|
||||
: undefined);
|
||||
`.then(({ rows }) => ({
|
||||
count: parseInt(rows[0].count, 10),
|
||||
...rows[0]?.start && rows[0]?.end
|
||||
? { dateRange: rows[0] as PhotoDateRange }
|
||||
: undefined,
|
||||
}));
|
||||
|
||||
const sqlGetPhotosCameraDateRange = async (camera: Camera) => sql`
|
||||
SELECT MIN(taken_at_naive) as start, MAX(taken_at_naive) as end
|
||||
@ -232,7 +229,7 @@ const sqlGetUniqueTags = async () => sql`
|
||||
WHERE hidden IS NOT TRUE
|
||||
GROUP BY tag
|
||||
ORDER BY tag ASC
|
||||
`.then(({ rows }): Tags => rows.map(({ tag, count }) => ({
|
||||
`.then(({ rows }): TagsWithMeta => rows.map(({ tag, count }) => ({
|
||||
tag: tag as string,
|
||||
count: parseInt(count, 10),
|
||||
})));
|
||||
@ -242,7 +239,7 @@ const sqlGetUniqueTagsHidden = async () => sql`
|
||||
FROM photos
|
||||
GROUP BY tag
|
||||
ORDER BY tag ASC
|
||||
`.then(({ rows }): Tags => rows.map(({ tag, count }) => ({
|
||||
`.then(({ rows }): TagsWithMeta => rows.map(({ tag, count }) => ({
|
||||
tag: tag as string,
|
||||
count: parseInt(count, 10),
|
||||
})));
|
||||
@ -461,15 +458,10 @@ export const getUniqueTags = () =>
|
||||
safelyQueryPhotos(sqlGetUniqueTags, 'getUniqueTags');
|
||||
export const getUniqueTagsHidden = () =>
|
||||
safelyQueryPhotos(sqlGetUniqueTagsHidden, 'getUniqueTagsHidden');
|
||||
export const getPhotosTagDateRange = (tag: string) =>
|
||||
export const getPhotosTagMeta = (tag: string) =>
|
||||
safelyQueryPhotos(
|
||||
() => sqlGetPhotosTagDateRange(tag),
|
||||
'getPhotosTagDateRange',
|
||||
);
|
||||
export const getPhotosTagCount = (tag: string) =>
|
||||
safelyQueryPhotos(
|
||||
() => sqlGetPhotosTagCount(tag),
|
||||
'getPhotosTagCount',
|
||||
() => sqlGetPhotosTagMeta(tag),
|
||||
'getPhotosTagMeta',
|
||||
);
|
||||
|
||||
// CAMERAS
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import {
|
||||
getPhotosCached,
|
||||
getPhotosTagCountCached,
|
||||
getPhotosTagDateRangeCached,
|
||||
getPhotosTagMetaCached,
|
||||
} from '@/photo/cache';
|
||||
import {
|
||||
PaginationSearchParams,
|
||||
@ -18,8 +17,7 @@ export const getPhotosTagDataCached = ({
|
||||
}) =>
|
||||
Promise.all([
|
||||
getPhotosCached({ tag, limit }),
|
||||
getPhotosTagCountCached(tag),
|
||||
getPhotosTagDateRangeCached(tag),
|
||||
getPhotosTagMetaCached(tag),
|
||||
]);
|
||||
|
||||
export const getPhotosTagDataCachedWithPagination = async ({
|
||||
@ -33,7 +31,7 @@ export const getPhotosTagDataCachedWithPagination = async ({
|
||||
}) => {
|
||||
const { offset, limit } = getPaginationFromSearchParams(searchParams);
|
||||
|
||||
const [photos, count, dateRange] =
|
||||
const [photos, { count, dateRange }] =
|
||||
await getPhotosTagDataCached({
|
||||
tag,
|
||||
limit: limitProp ?? limit,
|
||||
|
||||
@ -13,10 +13,13 @@ import { capitalizeWords, convertStringToArray } from '@/utility/string';
|
||||
|
||||
export const TAG_FAVS = 'favs';
|
||||
|
||||
export type Tags = {
|
||||
export type TagWithMeta = {
|
||||
tag: string
|
||||
count: number
|
||||
}[]
|
||||
dataRange?: PhotoDateRange
|
||||
}
|
||||
|
||||
export type TagsWithMeta = Omit<TagWithMeta, 'dateRange'>[]
|
||||
|
||||
export const formatTag = (tag?: string) =>
|
||||
capitalizeWords(tag?.replaceAll('-', ' '));
|
||||
@ -41,7 +44,7 @@ export const sortTags = (
|
||||
.sort((a, b) => isTagFavs(a) ? -1 : a.localeCompare(b));
|
||||
|
||||
export const sortTagsObject = (
|
||||
tags: Tags,
|
||||
tags: TagsWithMeta,
|
||||
tagToHide?: string,
|
||||
) => tags
|
||||
.filter(({ tag }) => tag!== tagToHide)
|
||||
@ -50,7 +53,7 @@ export const sortTagsObject = (
|
||||
export const sortTagsWithoutFavs = (tags: string[]) =>
|
||||
sortTags(tags, TAG_FAVS);
|
||||
|
||||
export const sortTagsObjectWithoutFavs = (tags: Tags) =>
|
||||
export const sortTagsObjectWithoutFavs = (tags: TagsWithMeta) =>
|
||||
sortTagsObject(tags, TAG_FAVS);
|
||||
|
||||
export const descriptionForTaggedPhotos = (
|
||||
|
||||
Loading…
Reference in New Issue
Block a user