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