prisma-sql 1.52.0 → 1.54.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/generator.cjs +238 -12
- package/dist/generator.cjs.map +1 -1
- package/dist/generator.js +238 -12
- package/dist/generator.js.map +1 -1
- package/package.json +1 -1
package/dist/generator.js
CHANGED
|
@@ -54,7 +54,7 @@ var require_package = __commonJS({
|
|
|
54
54
|
"package.json"(exports$1, module) {
|
|
55
55
|
module.exports = {
|
|
56
56
|
name: "prisma-sql",
|
|
57
|
-
version: "1.
|
|
57
|
+
version: "1.54.0",
|
|
58
58
|
description: "Convert Prisma queries to optimized SQL with type safety. 2-7x faster than Prisma Client.",
|
|
59
59
|
main: "dist/index.cjs",
|
|
60
60
|
module: "dist/index.js",
|
|
@@ -4951,12 +4951,98 @@ function generateCode(models, queries, dialect, datamodel) {
|
|
|
4951
4951
|
}));
|
|
4952
4952
|
const { mappings, fieldTypes } = extractEnumMappings(datamodel);
|
|
4953
4953
|
return `// Generated by @prisma-sql/generator - DO NOT EDIT
|
|
4954
|
-
import { buildSQL, transformQueryResults, type PrismaMethod, type Model } from 'prisma-sql'
|
|
4954
|
+
import { buildSQL, buildBatchSql, parseBatchResults, buildBatchCountSql, parseBatchCountResults, createTransactionExecutor, transformQueryResults, type PrismaMethod, type Model, type BatchQuery, type TransactionQuery, type TransactionOptions } from 'prisma-sql'
|
|
4955
|
+
|
|
4956
|
+
export interface BatchCountQuery {
|
|
4957
|
+
model: string
|
|
4958
|
+
method: 'count'
|
|
4959
|
+
args?: { where?: Record<string, unknown> }
|
|
4960
|
+
}
|
|
4961
|
+
|
|
4962
|
+
export interface TransactionQuery {
|
|
4963
|
+
model: string
|
|
4964
|
+
method: PrismaMethod
|
|
4965
|
+
args?: Record<string, unknown>
|
|
4966
|
+
}
|
|
4967
|
+
|
|
4968
|
+
export interface TransactionOptions {
|
|
4969
|
+
isolationLevel?: 'ReadCommitted' | 'RepeatableRead' | 'Serializable'
|
|
4970
|
+
timeout?: number
|
|
4971
|
+
}
|
|
4972
|
+
|
|
4973
|
+
class DeferredQuery {
|
|
4974
|
+
constructor(
|
|
4975
|
+
public readonly model: string,
|
|
4976
|
+
public readonly method: PrismaMethod,
|
|
4977
|
+
public readonly args: any,
|
|
4978
|
+
) {}
|
|
4979
|
+
|
|
4980
|
+
then(onfulfilled?: any, onrejected?: any): any {
|
|
4981
|
+
throw new Error(
|
|
4982
|
+
'Cannot await a batch query. Batch queries must not be awaited inside the $batch callback.',
|
|
4983
|
+
)
|
|
4984
|
+
}
|
|
4985
|
+
}
|
|
4986
|
+
|
|
4987
|
+
interface BatchProxy {
|
|
4988
|
+
[modelName: string]: {
|
|
4989
|
+
findMany: (args?: any) => DeferredQuery
|
|
4990
|
+
findFirst: (args?: any) => DeferredQuery
|
|
4991
|
+
findUnique: (args?: any) => DeferredQuery
|
|
4992
|
+
count: (args?: any) => DeferredQuery
|
|
4993
|
+
aggregate: (args?: any) => DeferredQuery
|
|
4994
|
+
groupBy: (args?: any) => DeferredQuery
|
|
4995
|
+
}
|
|
4996
|
+
}
|
|
4997
|
+
|
|
4998
|
+
const ACCELERATED_METHODS = new Set<PrismaMethod>([
|
|
4999
|
+
'findMany',
|
|
5000
|
+
'findFirst',
|
|
5001
|
+
'findUnique',
|
|
5002
|
+
'count',
|
|
5003
|
+
'aggregate',
|
|
5004
|
+
'groupBy',
|
|
5005
|
+
])
|
|
5006
|
+
|
|
5007
|
+
function createBatchProxy(): BatchProxy {
|
|
5008
|
+
return new Proxy(
|
|
5009
|
+
{},
|
|
5010
|
+
{
|
|
5011
|
+
get(_target, modelName: string): any {
|
|
5012
|
+
if (typeof modelName === 'symbol') return undefined
|
|
5013
|
+
|
|
5014
|
+
const model = MODEL_MAP.get(modelName)
|
|
5015
|
+
if (!model) {
|
|
5016
|
+
throw new Error(
|
|
5017
|
+
\`Model '\${modelName}' not found. Available: \${[...MODEL_MAP.keys()].join(', ')}\`,
|
|
5018
|
+
)
|
|
5019
|
+
}
|
|
5020
|
+
|
|
5021
|
+
return new Proxy(
|
|
5022
|
+
{},
|
|
5023
|
+
{
|
|
5024
|
+
get(_target, method: string): (args?: any) => DeferredQuery {
|
|
5025
|
+
if (!ACCELERATED_METHODS.has(method as PrismaMethod)) {
|
|
5026
|
+
throw new Error(
|
|
5027
|
+
\`Method '\${method}' not supported in batch. Supported: \${[...ACCELERATED_METHODS].join(', ')}\`,
|
|
5028
|
+
)
|
|
5029
|
+
}
|
|
5030
|
+
|
|
5031
|
+
return (args?: any): DeferredQuery => {
|
|
5032
|
+
return new DeferredQuery(
|
|
5033
|
+
modelName,
|
|
5034
|
+
method as PrismaMethod,
|
|
5035
|
+
args,
|
|
5036
|
+
)
|
|
5037
|
+
}
|
|
5038
|
+
},
|
|
5039
|
+
},
|
|
5040
|
+
)
|
|
5041
|
+
},
|
|
5042
|
+
},
|
|
5043
|
+
) as BatchProxy
|
|
5044
|
+
}
|
|
4955
5045
|
|
|
4956
|
-
/**
|
|
4957
|
-
* Normalize values for SQL params.
|
|
4958
|
-
* Synced from src/utils/normalize-value.ts
|
|
4959
|
-
*/
|
|
4960
5046
|
function normalizeValue(value: unknown, seen = new WeakSet<object>(), depth = 0): unknown {
|
|
4961
5047
|
const MAX_DEPTH = 20
|
|
4962
5048
|
if (depth > MAX_DEPTH) {
|
|
@@ -5003,9 +5089,6 @@ function normalizeValue(value: unknown, seen = new WeakSet<object>(), depth = 0)
|
|
|
5003
5089
|
return value
|
|
5004
5090
|
}
|
|
5005
5091
|
|
|
5006
|
-
/**
|
|
5007
|
-
* Get nested value from object using dot notation path
|
|
5008
|
-
*/
|
|
5009
5092
|
function getByPath(obj: any, path: string): unknown {
|
|
5010
5093
|
if (!obj || !path) return undefined
|
|
5011
5094
|
const keys = path.split('.')
|
|
@@ -5017,9 +5100,6 @@ function getByPath(obj: any, path: string): unknown {
|
|
|
5017
5100
|
return result
|
|
5018
5101
|
}
|
|
5019
5102
|
|
|
5020
|
-
/**
|
|
5021
|
-
* Normalize all params in array
|
|
5022
|
-
*/
|
|
5023
5103
|
function normalizeParams(params: unknown[]): unknown[] {
|
|
5024
5104
|
return params.map(p => normalizeValue(p))
|
|
5025
5105
|
}
|
|
@@ -5040,6 +5120,8 @@ const QUERIES: Record<string, Record<string, Record<string, {
|
|
|
5040
5120
|
|
|
5041
5121
|
const DIALECT = ${JSON.stringify(dialect)}
|
|
5042
5122
|
|
|
5123
|
+
const MODEL_MAP = new Map(MODELS.map(m => [m.name, m]))
|
|
5124
|
+
|
|
5043
5125
|
function isDynamicParam(key: string): boolean {
|
|
5044
5126
|
return key === 'skip' || key === 'take' || key === 'cursor'
|
|
5045
5127
|
}
|
|
@@ -5206,6 +5288,13 @@ async function executeQuery(client: any, sql: string, params: unknown[]): Promis
|
|
|
5206
5288
|
return stmt.all(...normalizedParams)
|
|
5207
5289
|
}
|
|
5208
5290
|
|
|
5291
|
+
async function executeRaw(client: any, sql: string, params?: unknown[]): Promise<unknown[]> {
|
|
5292
|
+
if (DIALECT === 'postgres') {
|
|
5293
|
+
return await client.unsafe(sql, (params || []) as any[])
|
|
5294
|
+
}
|
|
5295
|
+
throw new Error('Raw execution for sqlite not supported in transactions')
|
|
5296
|
+
}
|
|
5297
|
+
|
|
5209
5298
|
export function speedExtension(config: {
|
|
5210
5299
|
postgres?: any
|
|
5211
5300
|
sqlite?: any
|
|
@@ -5233,6 +5322,14 @@ export function speedExtension(config: {
|
|
|
5233
5322
|
}
|
|
5234
5323
|
|
|
5235
5324
|
return (prisma: any) => {
|
|
5325
|
+
const txExecutor = createTransactionExecutor({
|
|
5326
|
+
modelMap: MODEL_MAP,
|
|
5327
|
+
allModels: MODELS,
|
|
5328
|
+
dialect: DIALECT,
|
|
5329
|
+
executeRaw: (sql: string, params?: unknown[]) => executeRaw(client, sql, params),
|
|
5330
|
+
postgresClient: postgres,
|
|
5331
|
+
})
|
|
5332
|
+
|
|
5236
5333
|
const handleMethod = async function(this: any, method: PrismaMethod, args: any) {
|
|
5237
5334
|
const modelName = this?.name || this?.$name
|
|
5238
5335
|
const startTime = Date.now()
|
|
@@ -5286,11 +5383,130 @@ export function speedExtension(config: {
|
|
|
5286
5383
|
return transformQueryResults(method, results)
|
|
5287
5384
|
}
|
|
5288
5385
|
|
|
5386
|
+
async function batch<T extends Record<string, DeferredQuery>>(
|
|
5387
|
+
callback: (batch: BatchProxy) => T | Promise<T>,
|
|
5388
|
+
): Promise<{ [K in keyof T]: any }> {
|
|
5389
|
+
const batchProxy = createBatchProxy()
|
|
5390
|
+
const queries = await callback(batchProxy)
|
|
5391
|
+
|
|
5392
|
+
const batchQueries: Record<string, BatchQuery> = {}
|
|
5393
|
+
|
|
5394
|
+
for (const [key, deferred] of Object.entries(queries)) {
|
|
5395
|
+
if (!(deferred instanceof DeferredQuery)) {
|
|
5396
|
+
throw new Error(
|
|
5397
|
+
\`Batch query '\${key}' must be a deferred query. Did you await it?\`,
|
|
5398
|
+
)
|
|
5399
|
+
}
|
|
5400
|
+
|
|
5401
|
+
batchQueries[key] = {
|
|
5402
|
+
model: deferred.model,
|
|
5403
|
+
method: deferred.method,
|
|
5404
|
+
args: deferred.args || {},
|
|
5405
|
+
}
|
|
5406
|
+
}
|
|
5407
|
+
|
|
5408
|
+
const startTime = Date.now()
|
|
5409
|
+
const { sql, params, keys } = buildBatchSql(
|
|
5410
|
+
batchQueries,
|
|
5411
|
+
MODEL_MAP,
|
|
5412
|
+
MODELS,
|
|
5413
|
+
DIALECT,
|
|
5414
|
+
)
|
|
5415
|
+
|
|
5416
|
+
if (debug) {
|
|
5417
|
+
console.log(\`[\${DIALECT}] $batch (\${keys.length} queries)\`)
|
|
5418
|
+
console.log('SQL:', sql)
|
|
5419
|
+
console.log('Params:', params)
|
|
5420
|
+
}
|
|
5421
|
+
|
|
5422
|
+
const normalizedParams = normalizeParams(params)
|
|
5423
|
+
const rows = await client.unsafe(sql, normalizedParams as any[])
|
|
5424
|
+
const row = rows[0] as Record<string, unknown>
|
|
5425
|
+
const results = parseBatchResults(row, keys, batchQueries)
|
|
5426
|
+
const duration = Date.now() - startTime
|
|
5427
|
+
|
|
5428
|
+
onQuery?.({
|
|
5429
|
+
model: '_batch',
|
|
5430
|
+
method: 'batch',
|
|
5431
|
+
sql,
|
|
5432
|
+
params: normalizedParams,
|
|
5433
|
+
duration,
|
|
5434
|
+
prebaked: false,
|
|
5435
|
+
})
|
|
5436
|
+
|
|
5437
|
+
return results as { [K in keyof T]: any }
|
|
5438
|
+
}
|
|
5439
|
+
|
|
5440
|
+
async function batchCount(queries: BatchCountQuery[]): Promise<number[]> {
|
|
5441
|
+
if (queries.length === 0) return []
|
|
5442
|
+
|
|
5443
|
+
const startTime = Date.now()
|
|
5444
|
+
const { sql, params } = buildBatchCountSql(
|
|
5445
|
+
queries,
|
|
5446
|
+
MODEL_MAP,
|
|
5447
|
+
MODELS,
|
|
5448
|
+
DIALECT,
|
|
5449
|
+
)
|
|
5450
|
+
|
|
5451
|
+
if (debug) {
|
|
5452
|
+
console.log(\`[\${DIALECT}] $batchCount (\${queries.length} queries)\`)
|
|
5453
|
+
console.log('SQL:', sql)
|
|
5454
|
+
console.log('Params:', params)
|
|
5455
|
+
}
|
|
5456
|
+
|
|
5457
|
+
const normalizedParams = normalizeParams(params)
|
|
5458
|
+
const rows = await client.unsafe(sql, normalizedParams as any[])
|
|
5459
|
+
const row = rows[0] as Record<string, unknown>
|
|
5460
|
+
const results = parseBatchCountResults(row, queries.length)
|
|
5461
|
+
const duration = Date.now() - startTime
|
|
5462
|
+
|
|
5463
|
+
onQuery?.({
|
|
5464
|
+
model: '_batch',
|
|
5465
|
+
method: 'count',
|
|
5466
|
+
sql,
|
|
5467
|
+
params: normalizedParams,
|
|
5468
|
+
duration,
|
|
5469
|
+
prebaked: false,
|
|
5470
|
+
})
|
|
5471
|
+
|
|
5472
|
+
return results
|
|
5473
|
+
}
|
|
5474
|
+
|
|
5475
|
+
async function transaction(
|
|
5476
|
+
queries: TransactionQuery[],
|
|
5477
|
+
options?: TransactionOptions,
|
|
5478
|
+
): Promise<unknown[]> {
|
|
5479
|
+
const startTime = Date.now()
|
|
5480
|
+
|
|
5481
|
+
if (debug) {
|
|
5482
|
+
console.log(\`[\${DIALECT}] $transaction (\${queries.length} queries)\`)
|
|
5483
|
+
}
|
|
5484
|
+
|
|
5485
|
+
const results = await txExecutor.execute(queries, options)
|
|
5486
|
+
const duration = Date.now() - startTime
|
|
5487
|
+
|
|
5488
|
+
onQuery?.({
|
|
5489
|
+
model: '_transaction',
|
|
5490
|
+
method: 'count',
|
|
5491
|
+
sql: \`TRANSACTION(\${queries.length})\`,
|
|
5492
|
+
params: [],
|
|
5493
|
+
duration,
|
|
5494
|
+
prebaked: false,
|
|
5495
|
+
})
|
|
5496
|
+
|
|
5497
|
+
return results
|
|
5498
|
+
}
|
|
5499
|
+
|
|
5289
5500
|
return prisma.$extends({
|
|
5290
5501
|
name: 'prisma-sql-generated',
|
|
5291
5502
|
|
|
5292
5503
|
client: {
|
|
5293
5504
|
$original: prisma,
|
|
5505
|
+
$batch: batch as <T extends Record<string, DeferredQuery>>(
|
|
5506
|
+
callback: (batch: BatchProxy) => T | Promise<T>,
|
|
5507
|
+
) => Promise<{ [K in keyof T]: any }>,
|
|
5508
|
+
$batchCount: batchCount as (...args: any[]) => Promise<number[]>,
|
|
5509
|
+
$transaction: transaction as (...args: any[]) => Promise<unknown[]>,
|
|
5294
5510
|
},
|
|
5295
5511
|
|
|
5296
5512
|
model: {
|
|
@@ -5318,6 +5534,16 @@ export function speedExtension(config: {
|
|
|
5318
5534
|
})
|
|
5319
5535
|
}
|
|
5320
5536
|
}
|
|
5537
|
+
|
|
5538
|
+
type SpeedExtensionReturn = ReturnType<ReturnType<typeof speedExtension>>
|
|
5539
|
+
|
|
5540
|
+
export type SpeedClient<T> = T & {
|
|
5541
|
+
$batch<T extends Record<string, DeferredQuery>>(
|
|
5542
|
+
callback: (batch: BatchProxy) => T | Promise<T>,
|
|
5543
|
+
): Promise<{ [K in keyof T]: any }>
|
|
5544
|
+
$batchCount(queries: BatchCountQuery[]): Promise<number[]>
|
|
5545
|
+
$transaction(queries: TransactionQuery[], options?: TransactionOptions): Promise<unknown[]>
|
|
5546
|
+
}
|
|
5321
5547
|
`;
|
|
5322
5548
|
}
|
|
5323
5549
|
function formatQueries(queries) {
|