computeMatrix.ts•4.59 kB
import { AdapterProviders, Providers, RelationModes } from '../providers'
type ComputeMatrix = {
relationMode: 'prisma' | 'foreignKeys' | ''
}
export function computeMatrix({ relationMode }: ComputeMatrix) {
const driverAdapters = [
Providers.POSTGRESQL,
Providers.COCKROACHDB,
Providers.SQLSERVER,
Providers.SQLITE,
Providers.MYSQL,
] as const
// Note: SetDefault is not implemented in the emulation (relationMode="prisma")
// Note: testing 'SetDefault' requires a relation with a scalar field having the "@default" attribute.
// If no defaults are provided for any of the scalar fields, a runtime error will be thrown.
// Also 'SetDefault' is making SQL Server crash badly for example
// See https://www.notion.so/prismaio/Phase-1-Report-on-findings-f21c7bb079c5414296286973fdcd62c2#ac4d9f6a5d3842b5b6ff5b877e7e6782
const referentialActionsBase = ['DEFAULT', 'Cascade', 'NoAction', 'Restrict', 'SetNull'] as const
// "foreignKeys"
//
// 'Restrict' on SQL Server is not available and it triggers a schema parsing error.
// See in our docs https://pris.ly/d/relationMode
//
// `SetNull` with non-optional relations is invalid
// Previously, when using Foreign Keys it failed with migration errors on MySQL, CockroachDB and SQL Server, and at runtime for PostgreSQL
// A schema validation error was added in 4.6.0 making the schema invalid in that case.
// see https://github.com/prisma/prisma/issues/14673
//
// "prisma"
//
// `NoAction` on PostgreSQL / SQLite
// We made a schema validation error for PostgreSQL and SQLite in https://github.com/prisma/prisma-engines/pull/3274
// Error code: P1012 error: Error validating: Invalid referential action: `NoAction`. Allowed values: (`Cascade`, `Restrict`, `SetNull`). `NoAction` is not implemented for sqlite when using `relationMode = "prisma"`, you could try using `Restrict` instead. Learn more at https://pris.ly/d/relationMode
//
// We skip these combinations in the matrix (= filtering them out)
const referentialActionsDenylistByProviderFlavor = {
foreignKeys: {
[Providers.SQLSERVER]: ['Restrict'],
// skip all actions for Vitess & relationMode="foreignKeys" as Foreign Keys are not supported by that provider
[AdapterProviders.VITESS_8]: referentialActionsBase,
[AdapterProviders.JS_PLANETSCALE]: referentialActionsBase,
},
prisma: {
[Providers.SQLSERVER]: ['Restrict'],
[Providers.POSTGRESQL]: ['NoAction'],
[Providers.SQLITE]: ['NoAction'],
},
}
const providersMatrix = driverAdapters.map((provider) => ({
provider,
driverAdapter: undefined as AdapterProviders | undefined,
id: 'String @id',
relationMode,
}))
providersMatrix.push({
provider: Providers.MYSQL,
driverAdapter: AdapterProviders.VITESS_8,
id: 'String @id',
relationMode,
})
const referentialActionsMatrix = providersMatrix.flatMap((entry) => {
const denyList =
referentialActionsDenylistByProviderFlavor[relationMode || 'foreignKeys'][
entry.driverAdapter ?? entry.provider
] || []
const referentialActions = referentialActionsBase.filter((action) => !denyList.includes(action))
const referentialActionMatrixForSQL = referentialActions.map((referentialAction) => ({
...entry,
onUpdate: referentialAction,
onDelete: referentialAction,
}))
let referentialActionMatrixForMongoDB: any[] = []
// MongoDB
// Only has one mode that cannot be changed -> `relationMode = "prisma"`
// So we only run it
// when the datasource property relationMode is not set (default) or set to `prisma`.
// Which also matches the error expectations in our test suite
if (!relationMode || relationMode === RelationModes.PRISMA) {
const mongoDBMatrixBase = {
provider: Providers.MONGODB,
id: 'String @id @map("_id")',
relationMode: 'prisma',
}
referentialActionMatrixForMongoDB = [
{
...mongoDBMatrixBase,
onUpdate: 'DEFAULT',
onDelete: 'DEFAULT',
},
{
...mongoDBMatrixBase,
onUpdate: 'Cascade',
onDelete: 'Cascade',
},
{
...mongoDBMatrixBase,
onUpdate: 'NoAction',
onDelete: 'NoAction',
},
{
...mongoDBMatrixBase,
onUpdate: 'SetNull',
onDelete: 'SetNull',
},
]
}
return [...referentialActionMatrixForSQL, ...referentialActionMatrixForMongoDB]
})
return referentialActionsMatrix
}