Skip to content

Commit 7c779e4

Browse files
Restore typed SQL helper file
Co-authored-by: me <me@kentcdodds.com>
1 parent 6987c2f commit 7c779e4

4 files changed

Lines changed: 18 additions & 39 deletions

File tree

.cursor/rules/agents.mdc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22

33
- Use typed SQL (generated `sql` helpers with `prisma.$queryRawTyped`).
44
- Do not use `prisma.$queryRaw` or `Prisma.sql`.
5+
- Exception: Prisma typed SQL filenames must be valid JS identifiers (no dashes), so the lower-kebab-case rule does not apply under `prisma/sql/`.

app/routes/_app+/recipients+/_layout.tsx

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ import {
44
Outlet,
55
useLoaderData,
66
} from 'react-router'
7-
import * as prismaRuntime from '@prisma/client/runtime/client'
87
import { GeneralErrorBoundary } from '#app/components/error-boundary.tsx'
98
import { requireUserId } from '#app/utils/auth.server.js'
109
import { CronParseError, getScheduleWindow } from '#app/utils/cron.server.ts'
1110
import { prisma } from '#app/utils/db.server.ts'
11+
import { getunsentmessagecounts } from '#app/utils/prisma-generated.server/sql.ts'
1212
import {
1313
NEXT_SCHEDULE_SENTINEL_DATE,
1414
PREV_SCHEDULE_SENTINEL_DATE,
@@ -38,23 +38,6 @@ function formatScheduleDisplay(date: Date, timeZone: string) {
3838
const DEFAULT_RECIPIENTS_PAGE_SIZE = 200
3939
const MAX_RECIPIENTS_PAGE_SIZE = 1000
4040

41-
type UnsentMessageCountRow = {
42-
recipientId: string
43-
unsentCount: number | null
44-
}
45-
46-
const getUnsentMessageCounts = prismaRuntime.makeTypedQueryFactory(
47-
`SELECT
48-
recipientId,
49-
CAST(COUNT(*) AS INTEGER) AS unsentCount
50-
FROM Message INDEXED BY message_unsent_by_recipient
51-
WHERE sentAt IS NULL
52-
AND recipientId IN (SELECT value FROM json_each($1))
53-
GROUP BY recipientId;`,
54-
) as (
55-
recipientIdsJson: string,
56-
) => prismaRuntime.TypedSql<[recipientIdsJson: string], UnsentMessageCountRow>
57-
5841
function parsePageSize(value: string | null) {
5942
const parsed = Number(value ?? DEFAULT_RECIPIENTS_PAGE_SIZE)
6043
if (!Number.isFinite(parsed)) return DEFAULT_RECIPIENTS_PAGE_SIZE
@@ -88,7 +71,7 @@ export async function loader({ request }: LoaderFunctionArgs) {
8871
const recipientIds = recipients.map((recipient) => recipient.id)
8972
const messageCounts = recipientIds.length
9073
? await prisma.$queryRawTyped(
91-
getUnsentMessageCounts(JSON.stringify(recipientIds)),
74+
getunsentmessagecounts(JSON.stringify(recipientIds)),
9275
)
9376
: []
9477
const messageCountByRecipientId = new Map(
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
-- Count unsent messages for a list of recipient IDs.
2+
--
3+
-- @param {String} $1 - JSON array of recipient ids
4+
SELECT
5+
recipientId,
6+
CAST(COUNT(*) AS INTEGER) AS unsentCount
7+
FROM Message INDEXED BY message_unsent_by_recipient
8+
WHERE sentAt IS NULL
9+
AND recipientId IN (SELECT value FROM json_each($1))
10+
GROUP BY recipientId;

scripts/benchmark-performance.ts

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,17 @@
11
import 'dotenv/config'
22
import { performance } from 'node:perf_hooks'
33
import { parseArgs } from 'node:util'
4-
import * as prismaRuntime from '@prisma/client/runtime/client'
54
import { CronParseError, getScheduleWindow } from '#app/utils/cron.server.ts'
65
import { prisma } from '#app/utils/db.server.ts'
7-
import { getrecipientsforcron } from '#app/utils/prisma-generated.server/sql.ts'
6+
import {
7+
getrecipientsforcron,
8+
getunsentmessagecounts,
9+
} from '#app/utils/prisma-generated.server/sql.ts'
810
import { NEXT_SCHEDULE_SENTINEL_DATE } from '#app/utils/schedule-constants.server.ts'
911

1012
const MESSAGES_PER_PAGE = 100
1113
const RECIPIENTS_PAGE_SIZE = 200
1214

13-
type UnsentMessageCountRow = {
14-
recipientId: string
15-
unsentCount: number | null
16-
}
17-
18-
const getUnsentMessageCounts = prismaRuntime.makeTypedQueryFactory(
19-
`SELECT
20-
recipientId,
21-
CAST(COUNT(*) AS INTEGER) AS unsentCount
22-
FROM Message INDEXED BY message_unsent_by_recipient
23-
WHERE sentAt IS NULL
24-
AND recipientId IN (SELECT value FROM json_each($1))
25-
GROUP BY recipientId;`,
26-
) as (
27-
recipientIdsJson: string,
28-
) => prismaRuntime.TypedSql<[recipientIdsJson: string], UnsentMessageCountRow>
29-
3015
type Summary = {
3116
min: number
3217
max: number
@@ -146,7 +131,7 @@ async function benchmarkRecipientsList(
146131
const recipientIds = recipients.map((recipient) => recipient.id)
147132
const messageCounts = recipientIds.length
148133
? await prisma.$queryRawTyped(
149-
getUnsentMessageCounts(JSON.stringify(recipientIds)),
134+
getunsentmessagecounts(JSON.stringify(recipientIds)),
150135
)
151136
: []
152137
const messageCountByRecipientId = new Map(

0 commit comments

Comments
 (0)