Skip to content

Instantly share code, notes, and snippets.

@millsp
Last active June 3, 2023 02:55
Show Gist options
  • Save millsp/181b8757f7d08198200b427fc8f96bcf to your computer and use it in GitHub Desktop.
Save millsp/181b8757f7d08198200b427fc8f96bcf to your computer and use it in GitHub Desktop.
Example of a Prisma Client extensions that creates type-safe timing methods
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