Skip to content

Commit

Permalink
Merge pull request #28 from ethanniser/optimize-count
Browse files Browse the repository at this point in the history
Dedup + Cache queries
  • Loading branch information
RhysSullivan authored Oct 21, 2024
2 parents d5cebd7 + 83b225b commit fdba504
Show file tree
Hide file tree
Showing 13 changed files with 6,526 additions and 3,840 deletions.
10,045 changes: 6,339 additions & 3,706 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

14 changes: 3 additions & 11 deletions src/app/(category-sidebar)/[collection]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Link } from "@/components/ui/link";
import { db } from "@/db";
import { products } from "@/db/schema";
import { count } from "drizzle-orm";
import { getCollectionDetails } from "@/lib/queries";

import Image from "next/image";

export default async function Home(props: {
Expand All @@ -11,14 +10,7 @@ export default async function Home(props: {
}) {
const collectionName = decodeURIComponent((await props.params).collection);

const collections = await db.query.collections.findMany({
with: {
categories: true,
},
where: (collections, { eq }) =>
eq(collections.name, decodeURIComponent(collectionName)),
orderBy: (collections, { asc }) => asc(collections.name),
});
const collections = await getCollectionDetails(collectionName);
let imageCount = 0;

return (
Expand Down
9 changes: 2 additions & 7 deletions src/app/(category-sidebar)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
import { Link } from "@/components/ui/link";
import { db } from "@/db";
import { getCollections } from "@/lib/queries";

export default async function Layout({
children,
}: {
children: React.ReactNode;
}) {
const allCategories = await db.query.collections.findMany({
with: {
categories: true,
},
orderBy: (collections, { asc }) => asc(collections.name),
});
const allCategories = await getCollections();
return (
<div className="flex flex-grow overflow-hidden font-helvetica-roman">
<aside className="sticky hidden h-screen w-64 min-w-64 max-w-64 border-r p-4 md:block">
Expand Down
14 changes: 4 additions & 10 deletions src/app/(category-sidebar)/page.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
import { Link } from "@/components/ui/link";
import { db } from "@/db";
import { products } from "@/db/schema";
import { count } from "drizzle-orm";
import { getCollections, getProductCount } from "@/lib/queries";

import Image from "next/image";

export default async function Home() {
const [collections, productCount] = await Promise.all([
db.query.collections.findMany({
with: {
categories: true,
},
orderBy: (collections, { asc }) => asc(collections.name),
}),
db.select({ count: count() }).from(products),
getCollections(),
getProductCount(),
]);
let imageCount = 0;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { db } from "@/db";
import { ImageResponse } from "next/og";
import { notFound } from "next/navigation";
import { getProductDetails } from "@/lib/queries";

// Route segment config
export const runtime = "edge";
Expand All @@ -25,12 +25,8 @@ export default async function Image(props: {
console.log(props);
const { product } = await props.params;
const urlDecodedProduct = decodeURIComponent(product);
// const urlDecodedSubcategory = decodeURIComponent(subcategory);
// const urlDecodedCategory = decodeURIComponent(category);
const productData = await db.query.products.findFirst({
where: (products, { eq }) => eq(products.slug, urlDecodedProduct),
});
console.log(productData);
const productData = await getProductDetails(urlDecodedProduct);

if (!productData) {
notFound();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
import { ProductLink } from "@/components/ui/product-card";
import { db } from "@/db";
import Image from "next/image";
import { notFound } from "next/navigation";
import { AddToCartForm } from "@/components/add-to-cart-form";
import { Metadata } from "next";

import { getProductDetails, getProductsForSubcategory } from "@/lib/queries";

export async function generateMetadata(props: {
params: Promise<{ product: string; category: string; subcategory: string }>;
}): Promise<Metadata> {
const { product: productParam } = await props.params;
const urlDecodedProduct = decodeURIComponent(productParam);

const product = await db.query.products.findFirst({
where: (products, { eq }) => eq(products.slug, urlDecodedProduct),
orderBy: (products, { asc }) => asc(products.name),
});
const product = await getProductDetails(urlDecodedProduct);

if (!product) {
return notFound();
Expand All @@ -35,19 +33,10 @@ export default async function Page(props: {
const { product, subcategory, category } = await props.params;
const urlDecodedProduct = decodeURIComponent(product);
const urlDecodedSubcategory = decodeURIComponent(subcategory);
// const urlDecodedCategory = decodeURIComponent(category);
const productData = await db.query.products.findFirst({
where: (products, { eq }) => eq(products.slug, urlDecodedProduct),
});
const relatedUnshifted = await db.query.products.findMany({
where: (products, { eq, and }) =>
and(eq(products.subcategory_slug, urlDecodedSubcategory)),
with: {
subcategory: true,
},

orderBy: (products, { asc }) => asc(products.slug),
});
const [productData, relatedUnshifted] = await Promise.all([
getProductDetails(urlDecodedProduct),
getProductsForSubcategory(urlDecodedSubcategory),
]);

if (!productData) {
return notFound();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { db } from "@/db";
import { ImageResponse } from "next/og";
import { notFound } from "next/navigation";
import { getSubcategory } from "@/lib/queries";

// Route segment config
export const runtime = "edge";
Expand All @@ -24,11 +24,7 @@ export default async function Image(props: {
const { subcategory: subcategoryParam } = await props.params;
const urlDecodedCategory = decodeURIComponent(subcategoryParam);

const subcategory = await db.query.subcategories.findFirst({
where: (subcategories, { eq }) =>
eq(subcategories.slug, urlDecodedCategory),
orderBy: (categories, { asc }) => asc(categories.name),
});
const subcategory = await getSubcategory(urlDecodedCategory);

if (!subcategory) {
return notFound();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
import { notFound } from "next/navigation";
import { ProductLink } from "@/components/ui/product-card";
import { db } from "@/db";
import { products } from "@/db/schema";
import { count, eq } from "drizzle-orm";
import type { Metadata } from "next";
import {
getProductsForSubcategory,
getSubcategory,
getSubcategoryProductCount,
} from "@/lib/queries";

export async function generateMetadata(props: {
params: Promise<{ category: string; subcategory: string }>;
}): Promise<Metadata> {
const { subcategory: subcategoryParam } = await props.params;
const urlDecodedCategory = decodeURIComponent(subcategoryParam);

const subcategory = await db.query.subcategories.findFirst({
where: (subcategories, { eq }) =>
eq(subcategories.slug, urlDecodedCategory),
orderBy: (categories, { asc }) => asc(categories.name),
});

const rows = await db
.select({ count: count() })
.from(products)
.where(eq(products.subcategory_slug, urlDecodedCategory));
const [subcategory, rows] = await Promise.all([
getSubcategory(urlDecodedCategory),
getSubcategoryProductCount(urlDecodedCategory),
]);

if (!subcategory) {
return notFound();
Expand All @@ -44,24 +40,15 @@ export default async function Page(props: {
const { subcategory, category } = await props.params;
// const urlDecodedCategory = decodeURIComponent(category);
const urlDecodedSubcategory = decodeURIComponent(subcategory);
const sub = await db.query.subcategories.findFirst({
where: (subcategories, { eq }) =>
eq(subcategories.slug, urlDecodedSubcategory),
with: {
products: true,
},
orderBy: (subcategories, { asc }) => asc(subcategories.name),
});
const [products, countRes] = await Promise.all([
getProductsForSubcategory(urlDecodedSubcategory),
getSubcategoryProductCount(urlDecodedSubcategory),
]);

if (!sub) {
if (!products) {
return notFound();
}

const countRes = await db
.select({ count: count() })
.from(products)
.where(eq(products.subcategory_slug, urlDecodedSubcategory));

const finalCount = countRes[0]?.count;
return (
<div className="container mx-auto p-4">
Expand All @@ -73,7 +60,7 @@ export default async function Page(props: {
<p>No products for this subcategory</p>
)}
<div className="flex flex-row flex-wrap gap-2">
{sub.products.map((product) => (
{products.map((product) => (
<ProductLink
key={product.name}
loading="eager"
Expand Down
10 changes: 2 additions & 8 deletions src/app/(category-sidebar)/products/[category]/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Metadata } from "next";
import { db } from "../../../../db";
import { notFound } from "next/navigation";
import { getCategory } from "@/lib/queries";

export async function generateMetadata({
params,
Expand All @@ -9,13 +9,7 @@ export async function generateMetadata({
}): Promise<Metadata> {
const { category: categoryParam } = await params;
const urlDecoded = decodeURIComponent(categoryParam);
const category = await db.query.categories.findFirst({
where: (categories, { eq }) => eq(categories.slug, urlDecoded),
with: {
subcollections: true,
},
orderBy: (categories, { asc }) => asc(categories.name),
});
const category = await getCategory(urlDecoded);

if (!category) {
return notFound();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { db } from "@/db";
import { ImageResponse } from "next/og";
import { notFound } from "next/navigation";
import { getCategory } from "@/lib/queries";

// Route segment config
export const runtime = "edge";
Expand All @@ -23,13 +23,7 @@ export default async function Image(props: {
const { category: categoryParam } = await props.params;
const urlDecodedCategory = decodeURIComponent(categoryParam);

const category = await db.query.categories.findFirst({
where: (categories, { eq }) => eq(categories.slug, urlDecodedCategory),
with: {
subcollections: true,
},
orderBy: (categories, { asc }) => asc(categories.name),
});
const category = await getCategory(urlDecodedCategory);

if (!category) {
return notFound();
Expand Down
32 changes: 3 additions & 29 deletions src/app/(category-sidebar)/products/[category]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
import { db } from "@/db";
import {
categories,
products,
subcategories,
subcollection,
} from "@/db/schema";
import { count, eq } from "drizzle-orm";
import Image from "next/image";
import { Link } from "@/components/ui/link";
import { notFound } from "next/navigation";
import { getCategory, getCategoryProductCount } from "@/lib/queries";

export default async function Page(props: {
params: Promise<{
Expand All @@ -17,31 +10,12 @@ export default async function Page(props: {
}) {
const { category } = await props.params;
const urlDecoded = decodeURIComponent(category);
const cat = await db.query.categories.findFirst({
where: (categories, { eq }) => eq(categories.slug, urlDecoded),
with: {
subcollections: {
with: {
subcategories: true,
},
},
},
orderBy: (categories, { asc }) => asc(categories.name),
});
const cat = await getCategory(urlDecoded);
if (!cat) {
return notFound();
}

const countRes = await db
.select({ count: count() })
.from(categories)
.leftJoin(subcollection, eq(categories.slug, subcollection.category_slug))
.leftJoin(
subcategories,
eq(subcollection.id, subcategories.subcollection_id),
)
.leftJoin(products, eq(subcategories.slug, products.subcategory_slug))
.where(eq(categories.slug, cat.slug));
const countRes = await getCategoryProductCount(urlDecoded);

const finalCount = countRes[0]?.count;

Expand Down
Loading

0 comments on commit fdba504

Please sign in to comment.