Skip to content

Commit

Permalink
perf(client): Remove mappings from base dmmf (#18828)
Browse files Browse the repository at this point in the history
* perf(client): Remove `mappings` from base dmmf

Fix prisma/client-planning#320

* Better error for graphql action

* Add test for unsupported action

* Skip test on edge client
  • Loading branch information
SevInf committed Apr 20, 2023
1 parent b7f344d commit 49af45c
Show file tree
Hide file tree
Showing 13 changed files with 124 additions and 48 deletions.
4 changes: 2 additions & 2 deletions packages/client/src/generation/utils/buildDMMF.ts
Expand Up @@ -17,8 +17,8 @@ export function buildDMMF(compressed: boolean, dmmf: DMMF.Document) {
return buildCompressedDMMF(dmmfString)
}

const { datamodel, mappings } = dmmf
const dmmfString = escapeJson(JSON.stringify({ datamodel, mappings }))
const { datamodel } = dmmf
const dmmfString = escapeJson(JSON.stringify({ datamodel }))
return buildUncompressedDMMF(dmmfString)
}

Expand Down
@@ -1,6 +1,6 @@
import { DMMF } from '@prisma/generator-helper'

import { BaseDMMFHelper } from '../../dmmf'
import { DMMFDatamodelHelper } from '../../dmmf'
import { JsArgs, Selection } from '../types/JsApi'

type ModelVisitor = (value: object, model: DMMF.Model, queryArgs: JsArgs) => object | undefined
Expand All @@ -9,7 +9,7 @@ type VisitParams = {
result: object
args: JsArgs
model: DMMF.Model
dmmf: BaseDMMFHelper
dmmf: DMMFDatamodelHelper
visitor: ModelVisitor
}

Expand Down Expand Up @@ -50,7 +50,7 @@ type VisitNestedParams = {
includeOrSelect: Selection
result: object
parentModel: DMMF.Model
dmmf: BaseDMMFHelper
dmmf: DMMFDatamodelHelper
visitor: ModelVisitor
}

Expand Down
11 changes: 1 addition & 10 deletions packages/client/src/runtime/core/model/applyModel.ts
Expand Up @@ -69,7 +69,7 @@ function modelMetaLayer(dmmfModelName: string): CompositeProxyLayer {
function modelActionsLayer(client: Client, dmmfModelName: string): CompositeProxyLayer<string> {
// we use the javascript model name for display purposes
const jsModelName = dmmfToJSModelName(dmmfModelName)
const ownKeys = getOwnKeys(client, dmmfModelName)
const ownKeys = Object.keys(DMMF.ModelAction).concat('count')

return {
getKeys() {
Expand Down Expand Up @@ -127,15 +127,6 @@ function modelActionsLayer(client: Client, dmmfModelName: string): CompositeProx
}
}

function getOwnKeys(client: Client, dmmfModelName: string) {
const actionKeys = Object.keys(client._baseDmmf.mappingsMap[dmmfModelName]).filter(
(key) => key !== 'model' && key !== 'plural',
)
actionKeys.push('count')

return actionKeys
}

function isValidAggregateName(action: string): action is (typeof aggregateProps)[number] {
return (aggregateProps as readonly string[]).includes(action)
}
Expand Down
11 changes: 10 additions & 1 deletion packages/client/src/runtime/core/protocol/graphql.ts
Expand Up @@ -2,7 +2,8 @@ import { EngineBatchQuery, GraphQLQuery } from '@prisma/engine-core'

import { DMMFHelper } from '../../dmmf'
import { ErrorFormat } from '../../getPrismaClient'
import { Args, Document, makeDocument, unpack } from '../../query'
import { Args, Document, makeDocument, PrismaClientValidationError, unpack } from '../../query'
import { createErrorMessageWithContext } from '../../utils/createErrorMessageWithContext'
import { Action } from '../types/JsApi'
import { CreateMessageOptions, ProtocolEncoder, ProtocolMessage } from './common'

Expand Down Expand Up @@ -48,6 +49,14 @@ export class GraphQLProtocolEncoder implements ProtocolEncoder<GraphQLQuery> {
}

rootField = mapping[action === 'count' ? 'aggregate' : action]
if (!rootField) {
const message = createErrorMessageWithContext({
message: `Model \`${modelName}\` does not support \`${action}\` action.`,
originalMethod: clientMethod,
callsite: callsite,
})
throw new PrismaClientValidationError(message)
}
}

if (operation !== 'query' && operation !== 'mutation') {
Expand Down
@@ -1,14 +1,14 @@
import { EngineBatchQuery, JsonQuery, JsonQueryAction } from '@prisma/engine-core'

import { BaseDMMFHelper } from '../../../dmmf'
import { DMMFDatamodelHelper } from '../../../dmmf'
import { ErrorFormat } from '../../../getPrismaClient'
import { deepGet } from '../../../utils/deep-set'
import { CreateMessageOptions, ProtocolEncoder, ProtocolMessage } from '../common'
import { deserializeJsonResponse } from './deserialize'
import { serializeJsonQuery } from './serialize'

export class JsonProtocolEncoder implements ProtocolEncoder<JsonQuery> {
constructor(private baseDmmf: BaseDMMFHelper, private errorFormat: ErrorFormat) {}
constructor(private baseDmmf: DMMFDatamodelHelper, private errorFormat: ErrorFormat) {}

createMessage(createOptions: CreateMessageOptions): JsonProtocolMessage {
const query = serializeJsonQuery({ ...createOptions, baseDmmf: this.baseDmmf, errorFormat: this.errorFormat })
Expand Down
6 changes: 3 additions & 3 deletions packages/client/src/runtime/core/protocol/json/serialize.ts
Expand Up @@ -9,7 +9,7 @@ import {
import { DMMF } from '@prisma/generator-helper'
import { assertNever } from '@prisma/internals'

import { BaseDMMFHelper } from '../../../dmmf'
import { DMMFDatamodelHelper } from '../../../dmmf'
import { ErrorFormat } from '../../../getPrismaClient'
import { ObjectEnumValue, objectEnumValues } from '../../../object-enums'
import { CallSite } from '../../../utils/CallSite'
Expand Down Expand Up @@ -45,7 +45,7 @@ const jsActionToProtocolAction: Record<Action, JsonQueryAction> = {
}

export type SerializeParams = {
baseDmmf: BaseDMMFHelper
baseDmmf: DMMFDatamodelHelper
modelName?: string
action: Action
args?: JsArgs
Expand Down Expand Up @@ -247,7 +247,7 @@ function isRawParameters(value: JsInputValue): value is RawParameters {
}

type ContextParams = {
baseDmmf: BaseDMMFHelper
baseDmmf: DMMFDatamodelHelper
originalMethod: string
rootArgs: JsArgs | undefined
extensions: MergedExtensionsList
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/runtime/dmmf-types.ts
Expand Up @@ -2,4 +2,4 @@ import { DMMF } from '@prisma/generator-helper'

export { DMMF }

export type BaseDMMF = Pick<DMMF.Document, 'datamodel' | 'mappings'>
export type BaseDMMF = Pick<DMMF.Document, 'datamodel'>
18 changes: 4 additions & 14 deletions packages/client/src/runtime/dmmf.ts
@@ -1,11 +1,10 @@
import type { DMMF } from '@prisma/generator-helper'

import { BaseDMMF } from './dmmf-types'
import { applyMixins } from './utils/applyMixins'
import type { Dictionary } from './utils/common'
import { keyBy, ScalarTypeTable } from './utils/common'

class DMMFDatamodelHelper implements Pick<DMMF.Document, 'datamodel'> {
export class DMMFDatamodelHelper implements Pick<DMMF.Document, 'datamodel'> {
datamodel: DMMF.Datamodel
datamodelEnumMap: Dictionary<DMMF.DatamodelEnum>
modelMap: Dictionary<DMMF.Model>
Expand Down Expand Up @@ -238,20 +237,11 @@ class DMMFSchemaHelper implements Pick<DMMF.Document, 'schema'> {
}
}

export interface BaseDMMFHelper extends DMMFDatamodelHelper, DMMFMappingsHelper {}
export class BaseDMMFHelper {
constructor(dmmf: BaseDMMF) {
return Object.assign(this, new DMMFDatamodelHelper(dmmf), new DMMFMappingsHelper(dmmf))
}
}

applyMixins(BaseDMMFHelper, [DMMFDatamodelHelper, DMMFMappingsHelper])

export interface DMMFHelper extends BaseDMMFHelper, DMMFSchemaHelper {}
export interface DMMFHelper extends DMMFDatamodelHelper, DMMFMappingsHelper, DMMFSchemaHelper {}
export class DMMFHelper {
constructor(dmmf: DMMF.Document) {
return Object.assign(this, new BaseDMMFHelper(dmmf), new DMMFSchemaHelper(dmmf))
return Object.assign(this, new DMMFDatamodelHelper(dmmf), new DMMFMappingsHelper(dmmf), new DMMFSchemaHelper(dmmf))
}
}

applyMixins(DMMFHelper, [BaseDMMFHelper, DMMFSchemaHelper])
applyMixins(DMMFHelper, [DMMFDatamodelHelper, DMMFMappingsHelper, DMMFSchemaHelper])
6 changes: 3 additions & 3 deletions packages/client/src/runtime/getPrismaClient.ts
Expand Up @@ -58,7 +58,7 @@ import {
} from './core/request/PrismaPromise'
import { UserArgs } from './core/request/UserArgs'
import { getLockCountPromise } from './core/transaction/utils/createLockCountPromise'
import { BaseDMMFHelper, DMMFHelper } from './dmmf'
import { DMMFDatamodelHelper, DMMFHelper } from './dmmf'
import type { DMMF } from './dmmf-types'
import { getLogLevel } from './getLogLevel'
import { mergeBy } from './mergeBy'
Expand Down Expand Up @@ -297,7 +297,7 @@ export type Client = ReturnType<typeof getPrismaClient> extends new () => infer

export function getPrismaClient(config: GetPrismaClientConfig) {
class PrismaClient {
_baseDmmf: BaseDMMFHelper
_baseDmmf: DMMFDatamodelHelper
_dmmf?: DMMFHelper
_engine: Engine
_fetcher: RequestHandler
Expand Down Expand Up @@ -395,7 +395,7 @@ export function getPrismaClient(config: GetPrismaClientConfig) {
this._errorFormat = 'colorless' // default errorFormat
}

this._baseDmmf = new BaseDMMFHelper(config.document)
this._baseDmmf = new DMMFDatamodelHelper(config.document)
const engineProtocol = NODE_CLIENT
? getQueryEngineProtocol(config.generator)
: config.edgeClientProtocol ?? getQueryEngineProtocol(config.generator)
Expand Down
11 changes: 2 additions & 9 deletions packages/client/src/runtime/utils/datmodelBuilder.ts
@@ -1,6 +1,6 @@
import { DMMF } from '@prisma/generator-helper'

import { BaseDMMFHelper } from '../dmmf'
import { DMMFDatamodelHelper } from '../dmmf'

export function field(kind: DMMF.FieldKind, name: string, type: string, extra?: Partial<DMMF.Field>): DMMF.Field {
return {
Expand Down Expand Up @@ -38,18 +38,11 @@ export function model(name: string, fields: DMMF.Field[]): DMMF.Model {
}

export function baseDmmf({ models }: { models: DMMF.Model[] }) {
return new BaseDMMFHelper({
return new DMMFDatamodelHelper({
datamodel: {
models,
enums: [],
types: [],
},
mappings: {
modelOperations: [],
otherOperations: {
read: [],
write: [],
},
},
})
}
21 changes: 21 additions & 0 deletions packages/client/tests/functional/unsupported-action/_matrix.ts
@@ -0,0 +1,21 @@
import { defineMatrix } from '../_utils/defineMatrix'

export default defineMatrix(() => [
[
{
provider: 'sqlite',
},
{
provider: 'postgresql',
},
{
provider: 'mysql',
},
{
provider: 'cockroachdb',
},
{
provider: 'sqlserver',
},
],
])
@@ -0,0 +1,19 @@
import { idForProvider } from '../../_utils/idForProvider'
import testMatrix from '../_matrix'

export default testMatrix.setupSchema(({ provider }) => {
return /* Prisma */ `
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "${provider}"
url = env("DATABASE_URI_${provider}")
}
model User {
id ${idForProvider(provider)}
}
`
})
53 changes: 53 additions & 0 deletions packages/client/tests/functional/unsupported-action/tests.ts
@@ -0,0 +1,53 @@
import { getQueryEngineProtocol } from '@prisma/internals'

import testMatrix from './_matrix'
// @ts-ignore
import type { PrismaClient } from './node_modules/@prisma/client'

declare let prisma: PrismaClient

testMatrix.setupTestSuite(
() => {
testIf(getQueryEngineProtocol() === 'graphql')('unsupported method (graphql)', async () => {
// @ts-expect-error
const result = prisma.user.aggregateRaw()
await expect(result).rejects.toMatchPrismaErrorInlineSnapshot(`
Invalid \`prisma.user.aggregateRaw()\` invocation in
/client/tests/functional/unsupported-action/tests.ts:0:0
XX () => {
XX testIf(getQueryEngineProtocol() === 'graphql')('unsupported method (graphql)', async () => {
XX // @ts-expect-error
→ XX const result = prisma.user.aggregateRaw(
Model \`User\` does not support \`aggregateRaw\` action.
`)
})

testIf(getQueryEngineProtocol() === 'json')('unsupported method (json)', async () => {
// @ts-expect-error
const result = prisma.user.aggregateRaw()
await expect(result).rejects.toMatchPrismaErrorInlineSnapshot(`
Invalid \`prisma.user.aggregateRaw()\` invocation in
/client/tests/functional/unsupported-action/tests.ts:0:0
XX
XX testIf(getQueryEngineProtocol() === 'json')('unsupported method (json)', async () => {
XX // @ts-expect-error
→ XX const result = prisma.user.aggregateRaw(
Operation 'aggregateRaw' for model 'User' does not match any query.
`)
})
},
{
skipDataProxy: {
runtimes: ['edge'],
reason: 'Error rendering is different for edge client',
},
optOut: {
from: ['mongodb'],
reason: 'Test uses aggregateRaw as an example of unsupported method for SQL databases, it exists on mongo',
},
},
)

0 comments on commit 49af45c

Please sign in to comment.