Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Zaktualizowanie połączenia z Prismą #201

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@
"rules": {
"import/no-default-export": "off"
}
},
{
"files": ["**/*.d.ts"],
"rules": {
"no-var": "off"
}
}
]
}
4 changes: 1 addition & 3 deletions api-helpers/api-hofs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { createServerSupabaseClient } from '@supabase/auth-helpers-nextjs';
import { object } from 'yup';

import { logger } from './logger';
import { openConnection } from './prisma/db';
import { prisma } from './prisma/db';
import { handlePrismaError, isPrismaError } from './prisma/prisma-helper';

import type { Member, PrismaClient, UserRole } from '@prisma/client';
Expand Down Expand Up @@ -105,7 +105,6 @@ export const withAsync = (
logger.error(err instanceof Error ? err : { err });
return res.status(500).json(err);
}
} finally {
}
};
};
Expand All @@ -119,7 +118,6 @@ export const withDb =
) =>
(req: R, res: NextApiResponse) => {
try {
const prisma = openConnection();
return handler(unsafe__set(req, 'db', prisma), res);
} catch (err) {
if (isPrismaError(err)) {
Expand Down
22 changes: 12 additions & 10 deletions api-helpers/articles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ import {
} from '../constants';

import { HTTPNotFound } from './errors';

import type { PrismaClient } from '@prisma/client';
import { prisma } from './prisma/db';

// https://res.cloudinary.com/polskifrontend/image/fetch

export const getArticlesForGrid = async (prisma: PrismaClient, page: number) => {
const pageNumber = reversePageNumber(page, await getLastBlogPage(prisma));
export const getArticlesForGrid = async (page: number) => {
const lastBlogPage = await getLastBlogPage();
const pageNumber = reversePageNumber(page, lastBlogPage);

const blogs = await prisma.blog.findMany({
where: { isPublic: true },
skip: pageNumber * TILES_BLOGS_PER_PAGE,
Expand Down Expand Up @@ -53,14 +54,14 @@ export const getArticlesForGrid = async (prisma: PrismaClient, page: number) =>
};
};

export const getLastArticlePage = async (prisma: PrismaClient) => {
export const getLastArticlePage = async () => {
const articlesCount = await prisma.article.count({
where: { blog: { isPublic: true } },
});
return Math.ceil(articlesCount / LIST_ARTICLES_PER_PAGE);
};

export const getLastBlogPage = async (prisma: PrismaClient) => {
export const getLastBlogPage = async () => {
const blogCount = await prisma.blog.count({
where: { isPublic: true, lastArticlePublishedAt: { not: null } },
});
Expand All @@ -71,8 +72,9 @@ const reversePageNumber = (page: number, lastPage: number): number => {
return lastPage - page;
};

export const getArticlesForList = async (prisma: PrismaClient, page: number) => {
const pageNumber = reversePageNumber(page, await getLastArticlePage(prisma));
export const getArticlesForList = async (page: number) => {
const lastArticlePage = await getLastArticlePage();
const pageNumber = reversePageNumber(page, lastArticlePage);

const articles = await prisma.article.findMany({
skip: pageNumber * LIST_ARTICLES_PER_PAGE,
Expand Down Expand Up @@ -112,7 +114,7 @@ export const getArticlesForList = async (prisma: PrismaClient, page: number) =>
};
};

export const getArticlesSlugs = async (prisma: PrismaClient, limit?: number) => {
export const getArticlesSlugs = async (limit?: number) => {
const articles = await prisma.article.findMany({
where: {
blog: { isPublic: true },
Expand All @@ -129,7 +131,7 @@ export const getArticlesSlugs = async (prisma: PrismaClient, limit?: number) =>
return articles;
};

export const getArticleBySlug = async (prisma: PrismaClient, slug: string) => {
export const getArticleBySlug = async (slug: string) => {
const article = await prisma.article.findFirst({
where: {
slug,
Expand Down
34 changes: 6 additions & 28 deletions api-helpers/prisma/db.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,15 @@
import { PrismaClient } from '@prisma/client';

import { getConfig } from '../config';

// https://www.prisma.io/docs/support/help-articles/nextjs-prisma-client-dev-practices
declare global {
// allow global `var` declarations
// eslint-disable-next-line no-var -- global var required
var prisma: PrismaClient | undefined;
// eslint-disable-next-line no-var -- global var required
var prismaOpenConnections: number;
}
global.prismaOpenConnections = 0;
const getPrisma = () => {
if (process.env.NODE_ENV === 'production') {
return new PrismaClient();
}

export const openConnection = () => {
if (!global.prisma) {
// use pgbouncer
global.prisma = new PrismaClient({
datasources: {
db: {
url: getConfig('DATABASE_POOL_URL'),
},
},
});
global.prisma = new PrismaClient();
}

++global.prismaOpenConnections;
return global.prisma;
};

export const closeConnection = () => {
--global.prismaOpenConnections;
if (global.prismaOpenConnections === 0) {
return global.prisma?.$disconnect();
}
return undefined;
};
export const prisma = getPrisma();
10 changes: 4 additions & 6 deletions api-helpers/sitemap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import { getPagesArray } from '../utils/array-utils';

import { getLastArticlePage, getLastBlogPage, getArticlesSlugs } from './articles';

import type { PrismaClient } from '@prisma/client';

type Item = {
readonly path: string;
readonly changefreq: 'daily' | 'monthly' | 'always' | 'hourly' | 'weekly' | 'yearly' | 'never';
Expand All @@ -19,11 +17,11 @@ const staticItems: readonly Item[] = [
{ path: '/grid', changefreq: 'hourly', priority: 0.9 },
];

export async function getSitemap(prisma: PrismaClient) {
export async function getSitemap() {
const [gridLastPage, listLastPage, articleSlugs] = await Promise.all([
getLastBlogPage(prisma),
getLastArticlePage(prisma),
getArticlesSlugs(prisma),
getLastBlogPage(),
getLastArticlePage(),
getArticlesSlugs(),
]);
const gridPages = getPagesArray(gridLastPage);
const listPages = getPagesArray(listLastPage);
Expand Down
9 changes: 3 additions & 6 deletions app/(articles)/[displayStyle]/[page]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { getLastArticlePage, getLastBlogPage } from '../../../../api-helpers/articles';
import { openConnection } from '../../../../api-helpers/prisma/db';
import { BlogsGrid } from '../../../../components/BlogsGrid/BlogsGrid';
import { BlogsList } from '../../../../components/BlogsList/BlogsList';
import { getPagesArray } from '../../../../utils/array-utils';

import type { DisplayStyle } from '../../../../types';
import type { DisplayStyle } from '../../../../utils/types/types';

const MAX_PAGES = 5;

Expand All @@ -30,11 +29,9 @@ export default function HomePage({ params }: HomePageProps) {
}

export const generateStaticParams = async () => {
const prisma = openConnection();

const [gridLastPage, listLastPage] = await Promise.all([
await getLastBlogPage(prisma),
await getLastArticlePage(prisma),
await getLastBlogPage(),
await getLastArticlePage(),
]);

const gridPages = getPagesArray(gridLastPage, MAX_PAGES);
Expand Down
2 changes: 1 addition & 1 deletion app/(articles)/[displayStyle]/head.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { HeadTags } from '../../../components/HeadTags';

import type { DisplayStyle } from '../../../types';
import type { DisplayStyle } from '../../../utils/types/types';

type HeadProps = {
readonly params: {
Expand Down
2 changes: 1 addition & 1 deletion app/(articles)/[displayStyle]/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { AlgoliaSearch } from '../../../components/AlgoliaSearch/AlgoliaSearch';
import { SwitchDisplayStyle } from '../../../components/SwitchDisplayStyle/SwitchDisplayStyle';

import type { DisplayStyle } from '../../../types';
import type { DisplayStyle } from '../../../utils/types/types';
import type { ReactNode } from 'react';

type ArticlesLayoutProps = {
Expand Down
2 changes: 1 addition & 1 deletion app/(content)/admin/[blogsType]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { LogoutButton } from '../../../../components/LogoutButton/LogoutButton';
import { Table } from '../../../../components/Table/Table';
import { fetchAdminBlogsList } from '../../../../utils/fetchAdminBlogsList';

import type { BlogsType } from '../../../../types';
import type { BlogsType } from '../../../../utils/types/types';

type AdminPageProps = {
readonly params: {
Expand Down
4 changes: 1 addition & 3 deletions app/(content)/admin/blogs/[blogId]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { openConnection } from '../../../../../api-helpers/prisma/db';
import { prisma } from '../../../../../api-helpers/prisma/db';
import { ButtonAsLink } from '../../../../../components/ButtonAsLink/ButtonAsLink';
import { Content } from '../../../../../components/Content/Content';
import { ContentNavigation } from '../../../../../components/Content/ContentNavigation';
Expand Down Expand Up @@ -42,8 +42,6 @@ export default function AdminBlogPage({ params }: AdminBlogPageProps) {
}

export const generateStaticParams = async () => {
const prisma = openConnection();

const blogs = await prisma.blog.findMany();
const paths = blogs.map(({ id }) => ({ blogId: id }));

Expand Down
7 changes: 1 addition & 6 deletions app/(content)/artykuly/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { getArticlesSlugs } from '../../../../api-helpers/articles';
import { DEFAULT_ARTICLES } from '../../../../api-helpers/general-feed';
import { openConnection } from '../../../../api-helpers/prisma/db';
import { ArticleDate } from '../../../../components/ArticleDate/ArticleDate';
import { ButtonAsLink } from '../../../../components/ButtonAsLink/ButtonAsLink';
import { detectContentGenre } from '../../../../utils/creator-utils';
Expand Down Expand Up @@ -48,9 +47,5 @@ export default async function ArticlePage({ params }: ArticlePageProps) {
}

export const generateStaticParams = async () => {
const prisma = openConnection();

const articleSlugs = await getArticlesSlugs(prisma, DEFAULT_ARTICLES);

return articleSlugs;
return await getArticlesSlugs(DEFAULT_ARTICLES);
};
2 changes: 1 addition & 1 deletion components/AlgoliaSearch/AlgoliaHit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { memo } from 'react';
import { createExcerpt } from '../../utils/excerpt-utils';
import { ArticleTile } from '../ArticleTile/ArticleTile';

import type { Article, BlogFromArticle } from '../../types';
import type { Article, BlogFromArticle } from '../../utils/types/types';

export type Hit = {
readonly objectID: string;
Expand Down
2 changes: 1 addition & 1 deletion components/ArticleTile/ArticleTile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { ArticleDate } from '../ArticleDate/ArticleDate';

import Styles from './articleTile.module.scss';

import type { ArticleFromBlog, BlogFromArticle } from '../../types';
import type { ArticleFromBlog, BlogFromArticle } from '../../utils/types/types';

type ArticleTileProps = {
readonly article: ArticleFromBlog;
Expand Down
2 changes: 1 addition & 1 deletion components/ChangeBlogsList/ChangeBlogsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { useRouter } from 'next/navigation';

import type { BlogsType } from '../../types';
import type { BlogsType } from '../../utils/types/types';
import type { ChangeEvent } from 'react';

type ChangeBlogsListProps = {
Expand Down
2 changes: 1 addition & 1 deletion components/Pagination/Pagination.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ButtonAsLink } from '../ButtonAsLink/ButtonAsLink';

import type { DisplayStyle } from '../../types';
import type { DisplayStyle } from '../../utils/types/types';

type PaginationProps = {
readonly isFirstPage: boolean;
Expand Down
2 changes: 1 addition & 1 deletion components/Table/Table.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Styles from './table.module.scss';

import type { AdminTableBlogsRow } from '../../types';
import type { AdminTableBlogsRow } from '../../utils/types/types';

const columns = [
['link', 'Link do bloga'],
Expand Down
4 changes: 2 additions & 2 deletions pages/api/sitemap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { getSitemap } from '../../api-helpers/sitemap';

export default withAsync(
withMethods({
GET: withDb(async (req, res) => {
const sitemap = await getSitemap(req.db);
GET: withDb(async (_req, res) => {
const sitemap = await getSitemap();

res.setHeader('Content-Type', 'application/xml; charset=utf-8');
// 900 equals revalidation time (15 minutes)
Expand Down
2 changes: 1 addition & 1 deletion utils/creator-utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Article, Blog } from '../types';
import type { Article, Blog } from './types/types';

// Detect YouTube videos by the article URL
const ytRegex = /youtu(\.be|be\.com)\//;
Expand Down
6 changes: 2 additions & 4 deletions utils/fetchAdminBlogsList.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import Link from 'next/link';

import { openConnection } from '../api-helpers/prisma/db';
import { prisma } from '../api-helpers/prisma/db';

import { formatDate } from './date-utils';

import type { BlogsType } from '../types';
import type { BlogsType } from './types/types';

export const fetchAdminBlogsList = async (blogsType: BlogsType | undefined) => {
const prisma = openConnection();

const blogs = await prisma.blog.findMany({
where: {
isPublic: detectBlogsType(blogsType),
Expand Down
5 changes: 1 addition & 4 deletions utils/fetchArticleBySlug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { notFound } from 'next/navigation';

import { getArticleBySlug } from '../api-helpers/articles';
import { HTTPNotFound } from '../api-helpers/errors';
import { openConnection } from '../api-helpers/prisma/db';

import { addSanitizedDescriptionToArticle } from './sanitize-utils';

Expand All @@ -12,9 +11,7 @@ export const fetchArticleBySlug = async (slug: string | undefined) => {
}

try {
const prisma = openConnection();

const article = await getArticleBySlug(prisma, slug);
const article = await getArticleBySlug(slug);
const sanitizedArticle = addSanitizedDescriptionToArticle(article);

return sanitizedArticle;
Expand Down
7 changes: 2 additions & 5 deletions utils/fetchArticlesForList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,15 @@ import { notFound } from 'next/navigation';

import { getArticlesForList, getLastArticlePage } from '../api-helpers/articles';
import { HTTPNotFound } from '../api-helpers/errors';
import { openConnection } from '../api-helpers/prisma/db';

import { addExcerptToArticle } from './excerpt-utils';
import { pageValidGuard } from './pageValidGuard';

export const fetchArticlesForList = async (page?: string) => {
try {
const prisma = openConnection();

const lastPage = await getLastArticlePage(prisma);
const lastPage = await getLastArticlePage();
const pageNumber = pageValidGuard(page, lastPage);
const { data: articlesFromDb } = await getArticlesForList(prisma, pageNumber);
const { data: articlesFromDb } = await getArticlesForList(pageNumber);
const articles = articlesFromDb.map(addExcerptToArticle);

return {
Expand Down
7 changes: 2 additions & 5 deletions utils/fetchBlogsForGrid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,15 @@ import { notFound } from 'next/navigation';

import { getArticlesForGrid, getLastBlogPage } from '../api-helpers/articles';
import { HTTPNotFound } from '../api-helpers/errors';
import { openConnection } from '../api-helpers/prisma/db';

import { addExcerptToArticle } from './excerpt-utils';
import { pageValidGuard } from './pageValidGuard';

export const fetchBlogsForGrid = async (page?: string) => {
try {
const prisma = openConnection();

const lastPage = await getLastBlogPage(prisma);
const lastPage = await getLastBlogPage();
const pageNumber = pageValidGuard(page, lastPage);
const { data: blogsFromDb } = await getArticlesForGrid(prisma, pageNumber);
const { data: blogsFromDb } = await getArticlesForGrid(pageNumber);

const blogs = blogsFromDb.map((blog) => {
return {
Expand Down
Loading