Handle embedded pg schema name inside the table name when generating indexes (#7774)

This commit is contained in:
Harminder Virk
2024-06-19 16:48:44 +05:30
committed by GitHub
parent 0b623fa27a
commit fd87858bd9
4 changed files with 660 additions and 66 deletions

View File

@@ -89,4 +89,42 @@ describe("createPsqlIndexStatementHelper", function () {
}" (${options.columns.join(", ")}) WHERE ${options.where}`
)
})
it("should generate index on an explicit pg schema", function () {
const options = {
name: "index_name",
tableName: "public.table_name",
columns: "column_name",
}
const indexStatement = createPsqlIndexStatementHelper(options)
expect(indexStatement + "").toEqual(
`CREATE INDEX IF NOT EXISTS "${options.name}" ON "public"."table_name" (${options.columns})`
)
})
it("generate index name from table name when using explicit pg schema", function () {
const options = {
tableName: "public.table_name",
columns: "column_name",
}
const indexStatement = createPsqlIndexStatementHelper(options)
expect(indexStatement + "").toEqual(
`CREATE INDEX IF NOT EXISTS "IDX_table_name_column_name" ON "public"."table_name" (${options.columns})`
)
})
it("should generate index when table name was previously formatted to allow pg schema name", function () {
const options = {
name: "index_name",
tableName: 'public"."table_name',
columns: "column_name",
}
const indexStatement = createPsqlIndexStatementHelper(options)
expect(indexStatement + "").toEqual(
`CREATE INDEX IF NOT EXISTS "${options.name}" ON "public"."table_name" (${options.columns})`
)
})
})

View File

@@ -31,7 +31,7 @@ import { Index } from "@mikro-orm/core"
*/
export function createPsqlIndexStatementHelper({
name,
tableName,
tableName: qualifiedName,
columns,
type,
where,
@@ -45,6 +45,20 @@ export function createPsqlIndexStatementHelper({
unique?: boolean
}) {
const columnsName = Array.isArray(columns) ? columns.join("_") : columns
const tokens = qualifiedName.replace(/"/g, "").split(".")
let pgSchemaName: string | undefined
let tableName: string
let tableReference: string
if (tokens.length > 1) {
pgSchemaName = tokens.shift()
tableName = tokens.join(".")
tableReference = `"${pgSchemaName}"."${tableName}"`
} else {
tableName = qualifiedName
tableReference = `"${tableName}"`
}
columns = Array.isArray(columns) ? columns.join(", ") : columns
name = name || `IDX_${tableName}_${columnsName}${unique ? "_unique" : ""}`
@@ -53,7 +67,7 @@ export function createPsqlIndexStatementHelper({
const optionsStr = where ? ` WHERE ${where}` : ""
const uniqueStr = unique ? "UNIQUE " : ""
const expression = `CREATE ${uniqueStr}INDEX IF NOT EXISTS "${name}" ON "${tableName}"${typeStr} (${columns})${optionsStr}`
const expression = `CREATE ${uniqueStr}INDEX IF NOT EXISTS "${name}" ON ${tableReference}${typeStr} (${columns})${optionsStr}`
return {
toString: () => {
return expression

View File

@@ -669,6 +669,7 @@ describe("Entity builder", () => {
const metaData = MetadataStorage.getMetadataFromDecorator(User)
expect(metaData.className).toEqual("User")
expect(metaData.path).toEqual("User")
expect(metaData.tableName).toEqual("public.user")
expect(metaData.filters).toEqual({
softDeletable: {
@@ -772,9 +773,9 @@ describe("Entity builder", () => {
'CREATE INDEX IF NOT EXISTS "IDX_user_id" ON "user" (id) WHERE deleted_at IS NULL',
},
{
name: "IDX_user_email",
name: "IDX_user_email_unique",
expression:
'CREATE UNIQUE INDEX IF NOT EXISTS "IDX_user_email" ON "user" (email) WHERE deleted_at IS NULL',
'CREATE UNIQUE INDEX IF NOT EXISTS "IDX_user_email_unique" ON "user" (email) WHERE deleted_at IS NULL',
},
])
@@ -870,6 +871,7 @@ describe("Entity builder", () => {
const metaData = MetadataStorage.getMetadataFromDecorator(User)
expect(metaData.className).toEqual("User")
expect(metaData.path).toEqual("User")
expect(metaData.tableName).toEqual("platform.user")
expect(metaData.indexes).toEqual([
{
@@ -878,9 +880,9 @@ describe("Entity builder", () => {
'CREATE INDEX IF NOT EXISTS "IDX_user_id" ON "platform"."user" (id) WHERE deleted_at IS NULL',
},
{
name: "IDX_user_email",
name: "IDX_user_email_unique",
expression:
'CREATE UNIQUE INDEX IF NOT EXISTS "IDX_user_email" ON "platform"."user" (email) WHERE deleted_at IS NULL',
'CREATE UNIQUE INDEX IF NOT EXISTS "IDX_user_email_unique" ON "platform"."user" (email) WHERE deleted_at IS NULL',
},
])
@@ -2694,7 +2696,7 @@ describe("Entity builder", () => {
const entityBuilder = createMikrORMEntity()
expect(() => entityBuilder(email)).toThrow(
'Missing property "email" on "user" entity. Make sure to define it as a relationship'
'Missing property "email" on "User" entity. Make sure to define it as a relationship'
)
})
@@ -2715,7 +2717,7 @@ describe("Entity builder", () => {
const entityBuilder = createMikrORMEntity()
expect(() => entityBuilder(email)).toThrow(
'Invalid relationship reference for "email" on "user" entity. Make sure to define a hasOne or hasMany relationship'
'Invalid relationship reference for "email" on "User" entity. Make sure to define a hasOne or hasMany relationship'
)
})
@@ -2743,6 +2745,368 @@ describe("Entity builder", () => {
'Cannot cascade delete "user" relationship(s) from "email" entity. Child to parent cascades are not allowed'
)
})
test("define relationships when entity names has pg schema name", () => {
const model = new EntityBuilder()
const email = model.define("platform.email", {
email: model.text(),
isVerified: model.boolean(),
user: model.belongsTo(() => user),
})
const user = model.define("platform.user", {
id: model.number(),
username: model.text(),
email: model.hasOne(() => email),
})
const entityBuilder = createMikrORMEntity()
const User = entityBuilder(user)
const Email = entityBuilder(email)
expectTypeOf(new User()).toMatchTypeOf<{
id: number
username: string
deleted_at: Date | null
email: EntityConstructor<{
email: string
isVerified: boolean
deleted_at: Date | null
user: EntityConstructor<{
id: number
username: string
deleted_at: Date | null
}>
}>
}>()
expectTypeOf(new Email()).toMatchTypeOf<{
email: string
isVerified: boolean
deleted_at: Date | null
user: EntityConstructor<{
id: number
username: string
deleted_at: Date | null
email: EntityConstructor<{
email: string
isVerified: boolean
deleted_at: Date | null
}>
}>
}>()
const metaData = MetadataStorage.getMetadataFromDecorator(User)
expect(metaData.className).toEqual("User")
expect(metaData.path).toEqual("User")
expect(metaData.tableName).toEqual("platform.user")
expect(metaData.properties).toEqual({
id: {
reference: "scalar",
type: "number",
columnType: "integer",
name: "id",
nullable: false,
getter: false,
setter: false,
},
username: {
reference: "scalar",
type: "string",
columnType: "text",
name: "username",
nullable: false,
getter: false,
setter: false,
},
email: {
reference: "1:1",
name: "email",
entity: "Email",
nullable: false,
mappedBy: "user",
},
created_at: {
reference: "scalar",
type: "date",
columnType: "timestamptz",
name: "created_at",
defaultRaw: "now()",
onCreate: expect.any(Function),
nullable: false,
getter: false,
setter: false,
},
updated_at: {
reference: "scalar",
type: "date",
columnType: "timestamptz",
name: "updated_at",
defaultRaw: "now()",
onCreate: expect.any(Function),
onUpdate: expect.any(Function),
nullable: false,
getter: false,
setter: false,
},
deleted_at: {
reference: "scalar",
type: "date",
columnType: "timestamptz",
name: "deleted_at",
nullable: true,
getter: false,
setter: false,
},
})
const emailMetaData = MetadataStorage.getMetadataFromDecorator(Email)
expect(emailMetaData.className).toEqual("Email")
expect(emailMetaData.path).toEqual("Email")
expect(emailMetaData.tableName).toEqual("platform.email")
expect(emailMetaData.properties).toEqual({
email: {
reference: "scalar",
type: "string",
columnType: "text",
name: "email",
nullable: false,
getter: false,
setter: false,
},
isVerified: {
reference: "scalar",
type: "boolean",
columnType: "boolean",
name: "isVerified",
nullable: false,
getter: false,
setter: false,
},
user: {
reference: "1:1",
name: "user",
entity: "User",
nullable: false,
owner: true,
mappedBy: "email",
},
created_at: {
reference: "scalar",
type: "date",
columnType: "timestamptz",
name: "created_at",
defaultRaw: "now()",
onCreate: expect.any(Function),
nullable: false,
getter: false,
setter: false,
},
updated_at: {
reference: "scalar",
type: "date",
columnType: "timestamptz",
name: "updated_at",
defaultRaw: "now()",
onCreate: expect.any(Function),
onUpdate: expect.any(Function),
nullable: false,
getter: false,
setter: false,
},
deleted_at: {
reference: "scalar",
type: "date",
columnType: "timestamptz",
name: "deleted_at",
nullable: true,
getter: false,
setter: false,
},
})
})
test("define relationships between cross pg schemas entities", () => {
const model = new EntityBuilder()
const email = model.define("platform.email", {
email: model.text(),
isVerified: model.boolean(),
user: model.belongsTo(() => user),
})
const user = model.define("public.user", {
id: model.number(),
username: model.text(),
email: model.hasOne(() => email),
})
const entityBuilder = createMikrORMEntity()
const User = entityBuilder(user)
const Email = entityBuilder(email)
expectTypeOf(new User()).toMatchTypeOf<{
id: number
username: string
deleted_at: Date | null
email: EntityConstructor<{
email: string
isVerified: boolean
deleted_at: Date | null
user: EntityConstructor<{
id: number
username: string
deleted_at: Date | null
}>
}>
}>()
expectTypeOf(new Email()).toMatchTypeOf<{
email: string
isVerified: boolean
deleted_at: Date | null
user: EntityConstructor<{
id: number
username: string
deleted_at: Date | null
email: EntityConstructor<{
email: string
isVerified: boolean
deleted_at: Date | null
}>
}>
}>()
const metaData = MetadataStorage.getMetadataFromDecorator(User)
expect(metaData.className).toEqual("User")
expect(metaData.path).toEqual("User")
expect(metaData.tableName).toEqual("public.user")
expect(metaData.properties).toEqual({
id: {
reference: "scalar",
type: "number",
columnType: "integer",
name: "id",
nullable: false,
getter: false,
setter: false,
},
username: {
reference: "scalar",
type: "string",
columnType: "text",
name: "username",
nullable: false,
getter: false,
setter: false,
},
email: {
reference: "1:1",
name: "email",
entity: "Email",
nullable: false,
mappedBy: "user",
},
created_at: {
reference: "scalar",
type: "date",
columnType: "timestamptz",
name: "created_at",
defaultRaw: "now()",
onCreate: expect.any(Function),
nullable: false,
getter: false,
setter: false,
},
updated_at: {
reference: "scalar",
type: "date",
columnType: "timestamptz",
name: "updated_at",
defaultRaw: "now()",
onCreate: expect.any(Function),
onUpdate: expect.any(Function),
nullable: false,
getter: false,
setter: false,
},
deleted_at: {
reference: "scalar",
type: "date",
columnType: "timestamptz",
name: "deleted_at",
nullable: true,
getter: false,
setter: false,
},
})
const emailMetaData = MetadataStorage.getMetadataFromDecorator(Email)
expect(emailMetaData.className).toEqual("Email")
expect(emailMetaData.path).toEqual("Email")
expect(emailMetaData.tableName).toEqual("platform.email")
expect(emailMetaData.properties).toEqual({
email: {
reference: "scalar",
type: "string",
columnType: "text",
name: "email",
nullable: false,
getter: false,
setter: false,
},
isVerified: {
reference: "scalar",
type: "boolean",
columnType: "boolean",
name: "isVerified",
nullable: false,
getter: false,
setter: false,
},
user: {
reference: "1:1",
name: "user",
entity: "User",
nullable: false,
owner: true,
mappedBy: "email",
},
created_at: {
reference: "scalar",
type: "date",
columnType: "timestamptz",
name: "created_at",
defaultRaw: "now()",
onCreate: expect.any(Function),
nullable: false,
getter: false,
setter: false,
},
updated_at: {
reference: "scalar",
type: "date",
columnType: "timestamptz",
name: "updated_at",
defaultRaw: "now()",
onCreate: expect.any(Function),
onUpdate: expect.any(Function),
nullable: false,
getter: false,
setter: false,
},
deleted_at: {
reference: "scalar",
type: "date",
columnType: "timestamptz",
name: "deleted_at",
nullable: true,
getter: false,
setter: false,
},
})
})
})
describe("Entity builder | manyToMany", () => {
@@ -3100,7 +3464,7 @@ describe("Entity builder", () => {
const entityBuilder = createMikrORMEntity()
expect(() => entityBuilder(user)).toThrow(
'Missing property "users" on "team" entity. Make sure to define it as a relationship'
'Missing property "users" on "Team" entity. Make sure to define it as a relationship'
)
})
@@ -3120,7 +3484,7 @@ describe("Entity builder", () => {
const entityBuilder = createMikrORMEntity()
expect(() => entityBuilder(user)).toThrow(
'Invalid relationship reference for "users" on "team" entity. Make sure to define a manyToMany relationship'
'Invalid relationship reference for "users" on "Team" entity. Make sure to define a manyToMany relationship'
)
})
@@ -3680,5 +4044,176 @@ describe("Entity builder", () => {
},
})
})
test("define manyToMany relationship when entity names has pg schema name", () => {
const model = new EntityBuilder()
const team = model.define("platform.team", {
id: model.number(),
name: model.text(),
users: model.manyToMany(() => user),
})
const user = model.define("platform.user", {
id: model.number(),
username: model.text(),
teams: model.manyToMany(() => team),
})
const entityBuilder = createMikrORMEntity()
const User = entityBuilder(user)
const Team = entityBuilder(team)
expectTypeOf(new User()).toMatchTypeOf<{
id: number
username: string
teams: EntityConstructor<{
id: number
name: string
users: EntityConstructor<{
id: number
username: string
}>
}>
}>()
expectTypeOf(new Team()).toMatchTypeOf<{
id: number
name: string
users: EntityConstructor<{
id: number
username: string
teams: EntityConstructor<{
id: number
name: string
}>
}>
}>()
const metaData = MetadataStorage.getMetadataFromDecorator(User)
expect(metaData.className).toEqual("User")
expect(metaData.path).toEqual("User")
expect(metaData.tableName).toEqual("platform.user")
expect(metaData.properties).toEqual({
id: {
reference: "scalar",
type: "number",
columnType: "integer",
name: "id",
nullable: false,
getter: false,
setter: false,
},
username: {
reference: "scalar",
type: "string",
columnType: "text",
name: "username",
nullable: false,
getter: false,
setter: false,
},
teams: {
reference: "m:n",
name: "teams",
entity: "Team",
pivotTable: "platform.team_users",
},
created_at: {
reference: "scalar",
type: "date",
columnType: "timestamptz",
name: "created_at",
defaultRaw: "now()",
onCreate: expect.any(Function),
nullable: false,
getter: false,
setter: false,
},
updated_at: {
reference: "scalar",
type: "date",
columnType: "timestamptz",
name: "updated_at",
defaultRaw: "now()",
onCreate: expect.any(Function),
onUpdate: expect.any(Function),
nullable: false,
getter: false,
setter: false,
},
deleted_at: {
reference: "scalar",
type: "date",
columnType: "timestamptz",
name: "deleted_at",
nullable: true,
getter: false,
setter: false,
},
})
const teamMetaData = MetadataStorage.getMetadataFromDecorator(Team)
expect(teamMetaData.className).toEqual("Team")
expect(teamMetaData.path).toEqual("Team")
expect(teamMetaData.tableName).toEqual("platform.team")
expect(teamMetaData.properties).toEqual({
id: {
reference: "scalar",
type: "number",
columnType: "integer",
name: "id",
nullable: false,
getter: false,
setter: false,
},
name: {
reference: "scalar",
type: "string",
columnType: "text",
name: "name",
nullable: false,
getter: false,
setter: false,
},
users: {
reference: "m:n",
name: "users",
entity: "User",
pivotTable: "platform.team_users",
},
created_at: {
reference: "scalar",
type: "date",
columnType: "timestamptz",
name: "created_at",
defaultRaw: "now()",
onCreate: expect.any(Function),
nullable: false,
getter: false,
setter: false,
},
updated_at: {
reference: "scalar",
type: "date",
columnType: "timestamptz",
name: "updated_at",
defaultRaw: "now()",
onCreate: expect.any(Function),
onUpdate: expect.any(Function),
nullable: false,
getter: false,
setter: false,
},
deleted_at: {
reference: "scalar",
type: "date",
columnType: "timestamptz",
name: "deleted_at",
nullable: true,
getter: false,
setter: false,
},
})
})
})
})

View File

@@ -104,6 +104,33 @@ const SPECIAL_PROPERTIES: {
* to Mikro ORM entities.
*/
export function createMikrORMEntity() {
/**
* Parses entity name and returns model and table name from
* it
*/
function parseEntityName(entityName: string) {
/**
* Table name is going to be the snake case version of the entity name.
* Here we should preserve PG schema (if defined).
*
* For example: "platform.user" should stay as "platform.user"
*/
const tableName = camelToSnakeCase(entityName)
/**
* Entity name is going to be the camelCase version of the
* name defined by the user
*/
const [pgSchema, ...rest] = tableName.split(".")
return {
tableName,
modelName: upperCaseFirst(
toCamelCase(rest.length ? rest.join("_") : pgSchema)
),
pgSchema: rest.length ? pgSchema : undefined,
}
}
/**
* The following property is used to track many to many relationship
* between two entities. It is needed because we have to mark one
@@ -162,19 +189,12 @@ export function createMikrORMEntity() {
*/
function applyIndexes(
MikroORMEntity: EntityConstructor<any>,
{
tableName,
pgSchema,
}: { tableName: string; pgSchema: undefined | string },
tableName: string,
field: PropertyMetadata
) {
field.indexes.forEach((index) => {
const name =
index.name || `IDX_${tableName}_${camelToSnakeCase(field.fieldName)}`
const providerEntityIdIndexStatement = createPsqlIndexStatementHelper({
name,
tableName: pgSchema ? `${pgSchema}"."${tableName}` : tableName,
tableName,
columns: [field.fieldName],
unique: index.type === "unique",
where: "deleted_at IS NULL",
@@ -190,12 +210,9 @@ export function createMikrORMEntity() {
function defineHasOneRelationship(
MikroORMEntity: EntityConstructor<any>,
relationship: RelationshipMetadata,
relatedEntity: DmlEntity<
Record<string, PropertyType<any> | RelationshipType<any>>
>,
{ relatedModelName }: { relatedModelName: string },
cascades: EntityCascades<string[]>
) {
const relatedModelName = upperCaseFirst(relatedEntity.name)
const shouldRemoveRelated = !!cascades.delete?.includes(relationship.name)
OneToOne({
@@ -214,12 +231,9 @@ export function createMikrORMEntity() {
function defineHasManyRelationship(
MikroORMEntity: EntityConstructor<any>,
relationship: RelationshipMetadata,
relatedEntity: DmlEntity<
Record<string, PropertyType<any> | RelationshipType<any>>
>,
{ relatedModelName }: { relatedModelName: string },
cascades: EntityCascades<string[]>
) {
const relatedModelName = upperCaseFirst(relatedEntity.name)
const shouldRemoveRelated = !!cascades.delete?.includes(relationship.name)
OneToMany({
@@ -246,7 +260,8 @@ export function createMikrORMEntity() {
relationship: RelationshipMetadata,
relatedEntity: DmlEntity<
Record<string, PropertyType<any> | RelationshipType<any>>
>
>,
{ relatedModelName }: { relatedModelName: string }
) {
const mappedBy =
relationship.mappedBy || camelToSnakeCase(MikroORMEntity.name)
@@ -254,7 +269,6 @@ export function createMikrORMEntity() {
relatedEntity.parse()
const otherSideRelation = relationSchema[mappedBy]
const relatedModelName = upperCaseFirst(relatedEntity.name)
/**
* In DML the relationships are cascaded from parent to child. A belongsTo
@@ -269,7 +283,7 @@ export function createMikrORMEntity() {
*/
if (!otherSideRelation) {
throw new Error(
`Missing property "${mappedBy}" on "${relatedEntity.name}" entity. Make sure to define it as a relationship`
`Missing property "${mappedBy}" on "${relatedModelName}" entity. Make sure to define it as a relationship`
)
}
@@ -311,7 +325,7 @@ export function createMikrORMEntity() {
* Other side is some unsupported data-type
*/
throw new Error(
`Invalid relationship reference for "${mappedBy}" on "${relatedEntity.name}" entity. Make sure to define a hasOne or hasMany relationship`
`Invalid relationship reference for "${mappedBy}" on "${relatedModelName}" entity. Make sure to define a hasOne or hasMany relationship`
)
}
@@ -324,9 +338,11 @@ export function createMikrORMEntity() {
relatedEntity: DmlEntity<
Record<string, PropertyType<any> | RelationshipType<any>>
>,
cascades: EntityCascades<string[]>
{
relatedModelName,
pgSchema,
}: { relatedModelName: string; pgSchema: string | undefined }
) {
const relatedModelName = upperCaseFirst(relatedEntity.name)
let mappedBy = relationship.mappedBy
let inversedBy: undefined | string
@@ -340,7 +356,7 @@ export function createMikrORMEntity() {
*/
const pivotTableName = [
MikroORMEntity.name.toLowerCase(),
relatedEntity.name.toLowerCase(),
relatedModelName.toLowerCase(),
]
.sort()
.map((token, index) => {
@@ -355,13 +371,13 @@ export function createMikrORMEntity() {
const otherSideRelation = relatedEntity.parse().schema[mappedBy]
if (!otherSideRelation) {
throw new Error(
`Missing property "${mappedBy}" on "${relatedEntity.name}" entity. Make sure to define it as a relationship`
`Missing property "${mappedBy}" on "${relatedModelName}" entity. Make sure to define it as a relationship`
)
}
if (otherSideRelation instanceof DmlManyToMany === false) {
throw new Error(
`Invalid relationship reference for "${mappedBy}" on "${relatedEntity.name}" entity. Make sure to define a manyToMany relationship`
`Invalid relationship reference for "${mappedBy}" on "${relatedModelName}" entity. Make sure to define a manyToMany relationship`
)
}
@@ -387,7 +403,7 @@ export function createMikrORMEntity() {
ManyToMany({
entity: relatedModelName,
pivotTable: pivotTableName,
pivotTable: pgSchema ? `${pgSchema}.${pivotTableName}` : pivotTableName,
...(mappedBy ? { mappedBy: mappedBy as any } : {}),
...(inversedBy ? { inversedBy: inversedBy as any } : {}),
})(MikroORMEntity.prototype, relationship.name)
@@ -429,6 +445,15 @@ export function createMikrORMEntity() {
)
}
const { modelName, tableName, pgSchema } = parseEntityName(
relatedEntity.parse().name
)
const relatedEntityInfo = {
relatedModelName: modelName,
relatedTableName: tableName,
pgSchema,
}
/**
* Defining relationships
*/
@@ -437,7 +462,7 @@ export function createMikrORMEntity() {
defineHasOneRelationship(
MikroORMEntity,
relationship,
relatedEntity,
relatedEntityInfo,
cascades
)
break
@@ -445,19 +470,24 @@ export function createMikrORMEntity() {
defineHasManyRelationship(
MikroORMEntity,
relationship,
relatedEntity,
relatedEntityInfo,
cascades
)
break
case "belongsTo":
defineBelongsToRelationship(MikroORMEntity, relationship, relatedEntity)
defineBelongsToRelationship(
MikroORMEntity,
relationship,
relatedEntity,
relatedEntityInfo
)
break
case "manyToMany":
defineManyToManyRelationship(
MikroORMEntity,
relationship,
relatedEntity,
cascades
relatedEntityInfo
)
break
}
@@ -470,26 +500,7 @@ export function createMikrORMEntity() {
return function createEntity<T extends DmlEntity<any>>(entity: T): Infer<T> {
class MikroORMEntity {}
const { name, schema, cascades } = entity.parse()
const [pgSchema, ...rest] = name.split(".")
/**
* Entity name is computed by splitting the pgSchema
* from the original name and converting everything
* to camelCase
*/
const entityName = rest.length
? toCamelCase(rest.join("_"))
: toCamelCase(pgSchema)
/**
* Table name is the snake case version of entityName
*/
const tableName = camelToSnakeCase(entityName)
/**
* Table name is the Pascal case version of entityName
*/
const modelName = upperCaseFirst(entityName)
const { modelName, tableName } = parseEntityName(name)
/**
* Assigning name to the class constructor, so that it matches
@@ -508,11 +519,7 @@ export function createMikrORMEntity() {
const field = property.parse(name)
if ("fieldName" in field) {
defineProperty(MikroORMEntity, field)
applyIndexes(
MikroORMEntity,
{ tableName, pgSchema: rest.length ? pgSchema : undefined },
field
)
applyIndexes(MikroORMEntity, tableName, field)
} else {
defineRelationship(MikroORMEntity, field, cascades)
}