Last active
June 3, 2023 02:55
-
-
Save millsp/181b8757f7d08198200b427fc8f96bcf to your computer and use it in GitHub Desktop.
Example of a Prisma Client extensions that creates type-safe timing methods
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { PrismaClient, Prisma } from "@prisma/client" | |
type Operation = | |
| 'findFirst' | |
| 'findFirstOrThrow' | |
| 'findUnique' | |
| 'findUniqueOrThrow' | |
| 'findMany' | |
| 'create' | |
| 'createMany' | |
| 'update' | |
| 'updateMany' | |
| 'upsert' | |
| 'delete' | |
| 'deleteMany' | |
| 'aggregate' | |
| 'count' | |
| 'groupBy' | |
/** | |
* Create an operation extension that will time the operation. | |
* @param client The PrismaClient instance, ideally non extended. | |
* @param operation The operation to override. | |
* @returns | |
*/ | |
function createTimedOperation<O extends Operation>(client: any, operation: O) { | |
return async function <T, const A extends Prisma.Args<T, O>>(this: T, args: A, mutable?: { timing: number }) { | |
type Result = Prisma.Result<T, A, O> & { $timing: number } | |
const start = performance.now() | |
const model = Prisma.getExtensionContext(this).name | |
const result = await client[model][operation](args) as Result | |
const time = performance.now() - start | |
if (mutable !== undefined) { | |
mutable.timing = time | |
} | |
result.$timing = time | |
return result | |
} | |
} | |
async function main() { | |
const prisma = new PrismaClient() | |
const xprisma = prisma.$extends({ | |
model: { | |
$allModels: { | |
timedFindFirst: createTimedOperation(prisma, 'findFirst'), | |
timedFindFirstOrThrow: createTimedOperation(prisma, 'findFirstOrThrow'), | |
timedFindUnique: createTimedOperation(prisma, 'findUnique'), | |
timedFindUniqueOrThrow: createTimedOperation(prisma, 'findUniqueOrThrow'), | |
timedFindMany: createTimedOperation(prisma, 'findMany'), | |
timedCreate: createTimedOperation(prisma, 'create'), | |
timedCreateMany: createTimedOperation(prisma, 'createMany'), | |
timedUpdate: createTimedOperation(prisma, 'update'), | |
timedUpdateMany: createTimedOperation(prisma, 'updateMany'), | |
timedUpsert: createTimedOperation(prisma, 'upsert'), | |
timedDelete: createTimedOperation(prisma, 'delete'), | |
timedDeleteMany: createTimedOperation(prisma, 'deleteMany'), | |
timedAggregate: createTimedOperation(prisma, 'aggregate'), | |
timedCount: createTimedOperation(prisma, 'count'), | |
timedGroupBy: createTimedOperation(prisma, 'groupBy'), | |
} | |
} | |
}) | |
const email = `email@${Date.now()}` | |
await xprisma.user.create({ | |
data: { | |
email, | |
} | |
}) | |
const data = await xprisma.user.timedFindFirst({ | |
select: { email: true } | |
}) | |
console.log(data) | |
console.log(data.$timing) | |
} | |
void main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment