-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[0.2.0]:
custom_uniqueKey
field (#14)
* Add additional test and add complexity to example * Move findRandom functions to separate file * Change from 'defineExtension' to 'getExtensionContext' * Rename helper functions to match main functions * Introduce the custom_uniqueKey param * Bump version * Update copyright
- Loading branch information
Showing
8 changed files
with
135 additions
and
86 deletions.
There are no files selected for viewing
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
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,6 @@ | ||
import { PrismaClient } from '@prisma/client'; | ||
|
||
import prismaRandom from '../dist/index.js'; | ||
// import prismaRandom from '../src/index.js'; | ||
|
||
export const prisma = new PrismaClient().$extends(prismaRandom()); |
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { Prisma, User } from '@prisma/client'; | ||
|
||
// "User" types are used to simplify type inference | ||
|
||
export const $findRandom = async ( | ||
context: Prisma.UserDelegate, | ||
args?: Prisma.UserFindFirstArgs, | ||
): Promise<any> => { | ||
const numRows = await context.count({ | ||
where: args?.where, | ||
}); | ||
return await context.findFirst({ | ||
...args, | ||
skip: Math.max(0, Math.floor(Math.random() * numRows)), | ||
}); | ||
}; | ||
|
||
export const $findManyRandom = async ( | ||
context: Prisma.UserDelegate, | ||
num: number, | ||
args?: { | ||
select?: Prisma.UserFindFirstArgs['select']; | ||
where?: Prisma.UserFindFirstArgs['where']; | ||
custom_uniqueKey?: 'id'; | ||
}, | ||
): Promise<any> => { | ||
const uniqueKey = args?.custom_uniqueKey ?? 'id'; | ||
|
||
const rows = []; | ||
const rowIds: User['id'][] = []; | ||
|
||
const select = args?.select ?? {}; | ||
select[uniqueKey] = true; | ||
|
||
const where = args?.where ?? {}; | ||
where[uniqueKey] = { notIn: rowIds }; | ||
|
||
let numRows = await context.count({ where }); | ||
for (let i = 0; i < num && numRows > 0; ++i) { | ||
const row = await context.findFirst({ | ||
select, | ||
where, | ||
skip: Math.max(0, Math.floor(Math.random() * numRows)), | ||
}); | ||
|
||
if (!row) { | ||
console.error( | ||
`get random row failed. Where clause: ${JSON.stringify(where)}`, | ||
); | ||
break; | ||
} | ||
rows.push(row); | ||
rowIds.push(row[uniqueKey]); | ||
numRows--; | ||
} | ||
|
||
return rows; | ||
}; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,85 +1,54 @@ | ||
import { Prisma } from '@prisma/client'; | ||
import { $findManyRandom, $findRandom } from './helpers.js'; | ||
|
||
type Args = {}; | ||
|
||
export default (_extensionArgs?: Args) => | ||
Prisma.defineExtension((prisma) => { | ||
return prisma.$extends({ | ||
name: 'prisma-extension-random', | ||
model: { | ||
$allModels: { | ||
async findRandom<T, A>( | ||
this: T, | ||
args?: Prisma.Exact<A, Prisma.Args<T, 'findFirst'>> & object, | ||
) { | ||
const context = Prisma.getExtensionContext(this); | ||
|
||
const numRows = (await (context as any).count({ | ||
where: (args as { where?: object } | undefined)?.where, | ||
})) as number; | ||
return (await (context as any).findFirst({ | ||
...args, | ||
skip: Math.max(0, Math.floor(Math.random() * numRows)), | ||
})) as Prisma.Result<T, A, 'findFirst'>; | ||
}, | ||
Prisma.getExtensionContext({ | ||
name: 'prisma-extension-random', | ||
model: { | ||
$allModels: { | ||
async findRandom<T, A>( | ||
this: T, | ||
args?: Prisma.Exact<A, Prisma.Args<T, 'findFirst'>> & object, | ||
) { | ||
const context = Prisma.getExtensionContext(this); | ||
|
||
return (await $findRandom( | ||
context as any, | ||
args as any, | ||
)) as Prisma.Result<T, A, 'findFirst'>; | ||
}, | ||
|
||
async findManyRandom<T, TWhere, TSelect>( | ||
this: T, | ||
num: number, | ||
args?: { | ||
where?: Prisma.Exact< | ||
TWhere, | ||
Prisma.Args<T, 'findFirst'>['where'] | ||
>; | ||
select?: Prisma.Exact< | ||
TSelect, | ||
Prisma.Args<T, 'findFirst'>['select'] & { id: true } | ||
>; | ||
}, | ||
) { | ||
const context = Prisma.getExtensionContext(this); | ||
type FindFirstResult = Prisma.Result< | ||
T, | ||
{ where: TWhere; select: TSelect }, | ||
'findFirst' | ||
async findManyRandom<T, TWhere, TSelect, TUnique extends string>( | ||
this: T, | ||
num: number, | ||
args?: { | ||
where?: Prisma.Exact<TWhere, Prisma.Args<T, 'findFirst'>['where']>; | ||
select?: Prisma.Exact< | ||
TSelect, | ||
Prisma.Args<T, 'findFirst'>['select'] | ||
>; | ||
|
||
const select = args?.select ?? { id: true as const }; | ||
let where = args?.where ?? {}; | ||
|
||
let numRows = (await (context as any).count({ where })) as number; | ||
|
||
const rows: Array<NonNullable<FindFirstResult>> = []; | ||
const rowIds: string[] = []; | ||
|
||
where = { | ||
...where, | ||
id: { notIn: rowIds }, | ||
}; | ||
|
||
for (let i = 0; i < num && numRows > 0; ++i) { | ||
const row = (await (context as any).findFirst({ | ||
select, | ||
where, | ||
skip: Math.max(0, Math.floor(Math.random() * numRows)), | ||
})) as FindFirstResult; | ||
|
||
if (!row) { | ||
console.error( | ||
`get random row failed. Where clause: ${JSON.stringify( | ||
where, | ||
)}`, | ||
); | ||
break; | ||
} | ||
rows.push(row); | ||
rowIds.push((row as unknown as { id: string }).id); | ||
numRows--; | ||
} | ||
|
||
return rows; | ||
custom_uniqueKey?: TUnique; // TODO: add intellisense? | ||
}, | ||
) { | ||
const context = Prisma.getExtensionContext(this); | ||
type ExtendedSelect = TSelect & Record<TUnique, true>; | ||
|
||
return (await $findManyRandom( | ||
context as any, | ||
num, | ||
args as any, | ||
)) as Array< | ||
NonNullable< | ||
Prisma.Result< | ||
T, | ||
{ where: TWhere; select: ExtendedSelect }, | ||
'findFirst' | ||
> | ||
> | ||
>; | ||
}, | ||
}, | ||
}); | ||
}, | ||
}); |