• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

typeorm / typeorm / 19549987525

20 Nov 2025 08:11PM UTC coverage: 80.769% (+4.3%) from 76.433%
19549987525

push

github

web-flow
ci: run tests on commits to master and next (#11783)

Co-authored-by: Oleg "OSA413" Sokolov <OSA413@users.noreply.github.com>

26500 of 32174 branches covered (82.36%)

Branch coverage included in aggregate %.

91252 of 113615 relevant lines covered (80.32%)

88980.79 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.17
/src/metadata/EntityMetadata.ts
1
import { QueryRunner, SelectQueryBuilder } from ".."
26✔
2
import { ObjectLiteral } from "../common/ObjectLiteral"
26✔
3
import { DataSource } from "../data-source/DataSource"
26✔
4
import { CannotCreateEntityIdMapError } from "../error/CannotCreateEntityIdMapError"
26✔
5
import { OrderByCondition } from "../find-options/OrderByCondition"
26✔
6
import { TableMetadataArgs } from "../metadata-args/TableMetadataArgs"
26✔
7
import { TreeMetadataArgs } from "../metadata-args/TreeMetadataArgs"
26✔
8
import { OrmUtils } from "../util/OrmUtils"
26✔
9
import { CheckMetadata } from "./CheckMetadata"
26✔
10
import { ColumnMetadata } from "./ColumnMetadata"
26✔
11
import { EmbeddedMetadata } from "./EmbeddedMetadata"
26✔
12
import { EntityListenerMetadata } from "./EntityListenerMetadata"
26✔
13
import { ExclusionMetadata } from "./ExclusionMetadata"
26✔
14
import { ForeignKeyMetadata } from "./ForeignKeyMetadata"
26✔
15
import { IndexMetadata } from "./IndexMetadata"
26✔
16
import { RelationCountMetadata } from "./RelationCountMetadata"
26✔
17
import { RelationIdMetadata } from "./RelationIdMetadata"
26✔
18
import { RelationMetadata } from "./RelationMetadata"
26✔
19
import { TableType } from "./types/TableTypes"
26✔
20
import { TreeType } from "./types/TreeTypes"
26✔
21
import { UniqueMetadata } from "./UniqueMetadata"
26✔
22
import { ClosureTreeOptions } from "./types/ClosureTreeOptions"
26✔
23
import { EntityPropertyNotFoundError } from "../error/EntityPropertyNotFoundError"
26✔
24
import { ObjectUtils } from "../util/ObjectUtils"
26✔
25
import { shorten } from "../util/StringUtils"
26✔
26

26✔
27
/**
26✔
28
 * Contains all entity metadata.
26✔
29
 */
26✔
30
export class EntityMetadata {
26✔
31
    readonly "@instanceof" = Symbol.for("EntityMetadata")
26✔
32

26✔
33
    // -------------------------------------------------------------------------
26✔
34
    // Properties
26✔
35
    // -------------------------------------------------------------------------
26✔
36

26✔
37
    /**
26✔
38
     * Connection where this entity metadata is created.
26✔
39
     */
26✔
40
    connection: DataSource
26✔
41

26✔
42
    /**
26✔
43
     * Metadata arguments used to build this entity metadata.
26✔
44
     */
26✔
45
    tableMetadataArgs: TableMetadataArgs
26✔
46

26✔
47
    /**
26✔
48
     * If entity's table is a closure-typed table, then this entity will have a closure junction table metadata.
26✔
49
     */
26✔
50
    closureJunctionTable: EntityMetadata
26✔
51

26✔
52
    /**
26✔
53
     * If this is entity metadata for a junction closure table then its owner closure table metadata will be set here.
26✔
54
     */
26✔
55
    parentClosureEntityMetadata: EntityMetadata
26✔
56

26✔
57
    /**
26✔
58
     * Parent's entity metadata. Used in inheritance patterns.
26✔
59
     */
26✔
60
    parentEntityMetadata: EntityMetadata
26✔
61

26✔
62
    /**
26✔
63
     * Children entity metadatas. Used in inheritance patterns.
26✔
64
     */
26✔
65
    childEntityMetadatas: EntityMetadata[] = []
26✔
66

26✔
67
    /**
26✔
68
     * All "inheritance tree" from a target entity.
26✔
69
     * For example for target Post < ContentModel < Unit it will be an array of [Post, ContentModel, Unit].
26✔
70
     * It also contains child entities for single table inheritance.
26✔
71
     */
26✔
72
    inheritanceTree: Function[] = []
26✔
73

26✔
74
    /**
26✔
75
     * Table type. Tables can be closure, junction, etc.
26✔
76
     */
26✔
77
    tableType: TableType = "regular"
26✔
78

26✔
79
    /**
26✔
80
     * Target class to which this entity metadata is bind.
26✔
81
     * Note, that when using table inheritance patterns target can be different rather then table's target.
26✔
82
     * For virtual tables which lack of real entity (like junction tables) target is equal to their table name.
26✔
83
     */
26✔
84
    target: Function | string
26✔
85

26✔
86
    /**
26✔
87
     * Gets the name of the target.
26✔
88
     */
26✔
89
    targetName: string
26✔
90

26✔
91
    /**
26✔
92
     * Entity's name.
26✔
93
     * Equal to entity target class's name if target is set to table.
26✔
94
     * If target class is not then then it equals to table name.
26✔
95
     */
26✔
96
    name: string
26✔
97

26✔
98
    /**
26✔
99
     * View's expression.
26✔
100
     * Used in views
26✔
101
     */
26✔
102
    expression?: string | ((connection: DataSource) => SelectQueryBuilder<any>)
26✔
103

26✔
104
    /**
26✔
105
     * View's dependencies.
26✔
106
     * Used in views
26✔
107
     */
26✔
108
    dependsOn?: Set<Function | string>
26✔
109

26✔
110
    /**
26✔
111
     * Enables Sqlite "WITHOUT ROWID" modifier for the "CREATE TABLE" statement
26✔
112
     */
26✔
113
    withoutRowid?: boolean = false
26✔
114

26✔
115
    /**
26✔
116
     * Original user-given table name (taken from schema or @Entity(tableName) decorator).
26✔
117
     * If user haven't specified a table name this property will be undefined.
26✔
118
     */
26✔
119
    givenTableName?: string
26✔
120

26✔
121
    /**
26✔
122
     * Entity table name in the database.
26✔
123
     * This is final table name of the entity.
26✔
124
     * This name already passed naming strategy, and generated based on
26✔
125
     * multiple criteria, including user table name and global table prefix.
26✔
126
     */
26✔
127
    tableName: string
26✔
128

26✔
129
    /**
26✔
130
     * Entity table path. Contains database name, schema name and table name.
26✔
131
     * E.g. myDB.mySchema.myTable
26✔
132
     */
26✔
133
    tablePath: string
26✔
134

26✔
135
    /**
26✔
136
     * Gets the table name without global table prefix.
26✔
137
     * When querying table you need a table name with prefix, but in some scenarios,
26✔
138
     * for example when you want to name a junction table that contains names of two other tables,
26✔
139
     * you may want a table name without prefix.
26✔
140
     */
26✔
141
    tableNameWithoutPrefix: string
26✔
142

26✔
143
    /**
26✔
144
     * Indicates if schema will be synchronized for this entity or not.
26✔
145
     */
26✔
146
    synchronize: boolean = true
26✔
147

26✔
148
    /**
26✔
149
     * Table's database engine type (like "InnoDB", "MyISAM", etc).
26✔
150
     */
26✔
151
    engine?: string
26✔
152

26✔
153
    /**
26✔
154
     * Database name.
26✔
155
     */
26✔
156
    database?: string
26✔
157

26✔
158
    /**
26✔
159
     * Schema name. Used in Postgres and Sql Server.
26✔
160
     */
26✔
161
    schema?: string
26✔
162

26✔
163
    /**
26✔
164
     * Specifies a default order by used for queries from this table when no explicit order by is specified.
26✔
165
     */
26✔
166
    orderBy?: OrderByCondition
26✔
167

26✔
168
    /**
26✔
169
     * If this entity metadata's table using one of the inheritance patterns,
26✔
170
     * then this will contain what pattern it uses.
26✔
171
     */
26✔
172
    inheritancePattern?: "STI" /*|"CTI"*/
26✔
173

26✔
174
    /**
26✔
175
     * Checks if there any non-nullable column exist in this entity.
26✔
176
     */
26✔
177
    hasNonNullableRelations: boolean = false
26✔
178

26✔
179
    /**
26✔
180
     * Indicates if this entity metadata of a junction table, or not.
26✔
181
     * Junction table is a table created by many-to-many relationship.
26✔
182
     *
26✔
183
     * Its also possible to understand if entity is junction via tableType.
26✔
184
     */
26✔
185
    isJunction: boolean = false
26✔
186

26✔
187
    /**
26✔
188
     * Indicates if the entity should be instantiated using the constructor
26✔
189
     * or via allocating a new object via `Object.create()`.
26✔
190
     */
26✔
191
    isAlwaysUsingConstructor: boolean = true
26✔
192

26✔
193
    /**
26✔
194
     * Indicates if this entity is a tree, what type of tree it is.
26✔
195
     */
26✔
196
    treeType?: TreeType
26✔
197

26✔
198
    /**
26✔
199
     * Indicates if this entity is a tree, what options of tree it has.
26✔
200
     */
26✔
201
    treeOptions?: ClosureTreeOptions
26✔
202

26✔
203
    /**
26✔
204
     * Checks if this table is a junction table of the closure table.
26✔
205
     * This type is for tables that contain junction metadata of the closure tables.
26✔
206
     */
26✔
207
    isClosureJunction: boolean = false
26✔
208

26✔
209
    /**
26✔
210
     * Checks if entity's table has multiple primary columns.
26✔
211
     */
26✔
212
    hasMultiplePrimaryKeys: boolean = false
26✔
213

26✔
214
    /**
26✔
215
     * Indicates if this entity metadata has uuid generated columns.
26✔
216
     */
26✔
217
    hasUUIDGeneratedColumns: boolean = false
26✔
218

26✔
219
    /**
26✔
220
     * If this entity metadata is a child table of some table, it should have a discriminator value.
26✔
221
     * Used to store a value in a discriminator column.
26✔
222
     */
26✔
223
    discriminatorValue?: string
26✔
224

26✔
225
    /**
26✔
226
     * Entity's column metadatas defined by user.
26✔
227
     */
26✔
228
    ownColumns: ColumnMetadata[] = []
26✔
229

26✔
230
    /**
26✔
231
     * Columns of the entity, including columns that are coming from the embeddeds of this entity.
26✔
232
     */
26✔
233
    columns: ColumnMetadata[] = []
26✔
234

26✔
235
    /**
26✔
236
     * Ancestor columns used only in closure junction tables.
26✔
237
     */
26✔
238
    ancestorColumns: ColumnMetadata[] = []
26✔
239

26✔
240
    /**
26✔
241
     * Descendant columns used only in closure junction tables.
26✔
242
     */
26✔
243
    descendantColumns: ColumnMetadata[] = []
26✔
244

26✔
245
    /**
26✔
246
     * All columns except for virtual columns.
26✔
247
     */
26✔
248
    nonVirtualColumns: ColumnMetadata[] = []
26✔
249

26✔
250
    /**
26✔
251
     * In the case if this entity metadata is junction table's entity metadata,
26✔
252
     * this will contain all referenced columns of owner entity.
26✔
253
     */
26✔
254
    ownerColumns: ColumnMetadata[] = []
26✔
255

26✔
256
    /**
26✔
257
     * In the case if this entity metadata is junction table's entity metadata,
26✔
258
     * this will contain all referenced columns of inverse entity.
26✔
259
     */
26✔
260
    inverseColumns: ColumnMetadata[] = []
26✔
261

26✔
262
    /**
26✔
263
     * Gets the column with generated flag.
26✔
264
     */
26✔
265
    generatedColumns: ColumnMetadata[] = []
26✔
266

26✔
267
    /**
26✔
268
     * Gets the object id column used with mongodb database.
26✔
269
     */
26✔
270
    objectIdColumn?: ColumnMetadata
26✔
271

26✔
272
    /**
26✔
273
     * Gets entity column which contains a create date value.
26✔
274
     */
26✔
275
    createDateColumn?: ColumnMetadata
26✔
276

26✔
277
    /**
26✔
278
     * Gets entity column which contains an update date value.
26✔
279
     */
26✔
280
    updateDateColumn?: ColumnMetadata
26✔
281

26✔
282
    /**
26✔
283
     * Gets entity column which contains a delete date value.
26✔
284
     */
26✔
285
    deleteDateColumn?: ColumnMetadata
26✔
286

26✔
287
    /**
26✔
288
     * Gets entity column which contains an entity version.
26✔
289
     */
26✔
290
    versionColumn?: ColumnMetadata
26✔
291

26✔
292
    /**
26✔
293
     * Gets the discriminator column used to store entity identificator in single-table inheritance tables.
26✔
294
     */
26✔
295
    discriminatorColumn?: ColumnMetadata
26✔
296

26✔
297
    /**
26✔
298
     * Special column that stores tree level in tree entities.
26✔
299
     */
26✔
300
    treeLevelColumn?: ColumnMetadata
26✔
301

26✔
302
    /**
26✔
303
     * Nested set's left value column.
26✔
304
     * Used only in tree entities with nested set pattern applied.
26✔
305
     */
26✔
306
    nestedSetLeftColumn?: ColumnMetadata
26✔
307

26✔
308
    /**
26✔
309
     * Nested set's right value column.
26✔
310
     * Used only in tree entities with nested set pattern applied.
26✔
311
     */
26✔
312
    nestedSetRightColumn?: ColumnMetadata
26✔
313

26✔
314
    /**
26✔
315
     * Materialized path column.
26✔
316
     * Used only in tree entities with materialized path pattern applied.
26✔
317
     */
26✔
318
    materializedPathColumn?: ColumnMetadata
26✔
319

26✔
320
    /**
26✔
321
     * Gets the primary columns.
26✔
322
     */
26✔
323
    primaryColumns: ColumnMetadata[] = []
26✔
324

26✔
325
    /**
26✔
326
     * Entity's relation metadatas.
26✔
327
     */
26✔
328
    ownRelations: RelationMetadata[] = []
26✔
329

26✔
330
    /**
26✔
331
     * Relations of the entity, including relations that are coming from the embeddeds of this entity.
26✔
332
     */
26✔
333
    relations: RelationMetadata[] = []
26✔
334

26✔
335
    /**
26✔
336
     * List of eager relations this metadata has.
26✔
337
     */
26✔
338
    eagerRelations: RelationMetadata[] = []
26✔
339

26✔
340
    /**
26✔
341
     * List of eager relations this metadata has.
26✔
342
     */
26✔
343
    lazyRelations: RelationMetadata[] = []
26✔
344

26✔
345
    /**
26✔
346
     * Gets only one-to-one relations of the entity.
26✔
347
     */
26✔
348
    oneToOneRelations: RelationMetadata[] = []
26✔
349

26✔
350
    /**
26✔
351
     * Gets only owner one-to-one relations of the entity.
26✔
352
     */
26✔
353
    ownerOneToOneRelations: RelationMetadata[] = []
26✔
354

26✔
355
    /**
26✔
356
     * Gets only one-to-many relations of the entity.
26✔
357
     */
26✔
358
    oneToManyRelations: RelationMetadata[] = []
26✔
359

26✔
360
    /**
26✔
361
     * Gets only many-to-one relations of the entity.
26✔
362
     */
26✔
363
    manyToOneRelations: RelationMetadata[] = []
26✔
364

26✔
365
    /**
26✔
366
     * Gets only many-to-many relations of the entity.
26✔
367
     */
26✔
368
    manyToManyRelations: RelationMetadata[] = []
26✔
369

26✔
370
    /**
26✔
371
     * Gets only owner many-to-many relations of the entity.
26✔
372
     */
26✔
373
    ownerManyToManyRelations: RelationMetadata[] = []
26✔
374

26✔
375
    /**
26✔
376
     * Gets only owner one-to-one and many-to-one relations.
26✔
377
     */
26✔
378
    relationsWithJoinColumns: RelationMetadata[] = []
26✔
379

26✔
380
    /**
26✔
381
     * Tree parent relation. Used only in tree-tables.
26✔
382
     */
26✔
383
    treeParentRelation?: RelationMetadata
26✔
384

26✔
385
    /**
26✔
386
     * Tree children relation. Used only in tree-tables.
26✔
387
     */
26✔
388
    treeChildrenRelation?: RelationMetadata
26✔
389

26✔
390
    /**
26✔
391
     * Entity's relation id metadatas.
26✔
392
     */
26✔
393
    relationIds: RelationIdMetadata[] = []
26✔
394

26✔
395
    /**
26✔
396
     * Entity's relation id metadatas.
26✔
397
     */
26✔
398
    relationCounts: RelationCountMetadata[] = []
26✔
399

26✔
400
    /**
26✔
401
     * Entity's foreign key metadatas.
26✔
402
     */
26✔
403
    foreignKeys: ForeignKeyMetadata[] = []
26✔
404

26✔
405
    /**
26✔
406
     * Entity's embedded metadatas.
26✔
407
     */
26✔
408
    embeddeds: EmbeddedMetadata[] = []
26✔
409

26✔
410
    /**
26✔
411
     * All embeddeds - embeddeds from this entity metadata and from all child embeddeds, etc.
26✔
412
     */
26✔
413
    allEmbeddeds: EmbeddedMetadata[] = []
26✔
414

26✔
415
    /**
26✔
416
     * Entity's own indices.
26✔
417
     */
26✔
418
    ownIndices: IndexMetadata[] = []
26✔
419

26✔
420
    /**
26✔
421
     * Entity's index metadatas.
26✔
422
     */
26✔
423
    indices: IndexMetadata[] = []
26✔
424

26✔
425
    /**
26✔
426
     * Entity's unique metadatas.
26✔
427
     */
26✔
428
    uniques: UniqueMetadata[] = []
26✔
429

26✔
430
    /**
26✔
431
     * Entity's own uniques.
26✔
432
     */
26✔
433
    ownUniques: UniqueMetadata[] = []
26✔
434

26✔
435
    /**
26✔
436
     * Entity's check metadatas.
26✔
437
     */
26✔
438
    checks: CheckMetadata[] = []
26✔
439

26✔
440
    /**
26✔
441
     * Entity's exclusion metadatas.
26✔
442
     */
26✔
443
    exclusions: ExclusionMetadata[] = []
26✔
444

26✔
445
    /**
26✔
446
     * Entity's own listener metadatas.
26✔
447
     */
26✔
448
    ownListeners: EntityListenerMetadata[] = []
26✔
449

26✔
450
    /**
26✔
451
     * Entity listener metadatas.
26✔
452
     */
26✔
453
    listeners: EntityListenerMetadata[] = []
26✔
454

26✔
455
    /**
26✔
456
     * Listener metadatas with "AFTER LOAD" type.
26✔
457
     */
26✔
458
    afterLoadListeners: EntityListenerMetadata[] = []
26✔
459

26✔
460
    /**
26✔
461
     * Listener metadatas with "BEFORE INSERT" type.
26✔
462
     */
26✔
463
    beforeInsertListeners: EntityListenerMetadata[] = []
26✔
464

26✔
465
    /**
26✔
466
     * Listener metadatas with "AFTER INSERT" type.
26✔
467
     */
26✔
468
    afterInsertListeners: EntityListenerMetadata[] = []
26✔
469

26✔
470
    /**
26✔
471
     * Listener metadatas with "BEFORE UPDATE" type.
26✔
472
     */
26✔
473
    beforeUpdateListeners: EntityListenerMetadata[] = []
26✔
474

26✔
475
    /**
26✔
476
     * Listener metadatas with "AFTER UPDATE" type.
26✔
477
     */
26✔
478
    afterUpdateListeners: EntityListenerMetadata[] = []
26✔
479

26✔
480
    /**
26✔
481
     * Listener metadatas with "BEFORE REMOVE" type.
26✔
482
     */
26✔
483
    beforeRemoveListeners: EntityListenerMetadata[] = []
26✔
484

26✔
485
    /**
26✔
486
     * Listener metadatas with "BEFORE SOFT REMOVE" type.
26✔
487
     */
26✔
488
    beforeSoftRemoveListeners: EntityListenerMetadata[] = []
26✔
489

26✔
490
    /**
26✔
491
     * Listener metadatas with "BEFORE RECOVER" type.
26✔
492
     */
26✔
493
    beforeRecoverListeners: EntityListenerMetadata[] = []
26✔
494

26✔
495
    /**
26✔
496
     * Listener metadatas with "AFTER REMOVE" type.
26✔
497
     */
26✔
498
    afterRemoveListeners: EntityListenerMetadata[] = []
26✔
499

26✔
500
    /**
26✔
501
     * Listener metadatas with "AFTER SOFT REMOVE" type.
26✔
502
     */
26✔
503
    afterSoftRemoveListeners: EntityListenerMetadata[] = []
26✔
504

26✔
505
    /**
26✔
506
     * Listener metadatas with "AFTER RECOVER" type.
26✔
507
     */
26✔
508
    afterRecoverListeners: EntityListenerMetadata[] = []
26✔
509

26✔
510
    /**
26✔
511
     * Map of columns and relations of the entity.
26✔
512
     *
26✔
513
     * example: Post{ id: number, name: string, counterEmbed: { count: number }, category: Category }.
26✔
514
     * This method will create following object:
26✔
515
     * { id: "id", counterEmbed: { count: "counterEmbed.count" }, category: "category" }
26✔
516
     */
26✔
517
    propertiesMap: ObjectLiteral
26✔
518

26✔
519
    /**
26✔
520
     * Table comment. Not supported by all database types.
26✔
521
     */
26✔
522
    comment?: string
26✔
523

26✔
524
    // ---------------------------------------------------------------------
26✔
525
    // Constructor
26✔
526
    // ---------------------------------------------------------------------
26✔
527

26✔
528
    constructor(options: {
26✔
529
        connection: DataSource
36,604✔
530
        inheritanceTree?: Function[]
36,604✔
531
        inheritancePattern?: "STI" /*|"CTI"*/
36,604✔
532
        tableTree?: TreeMetadataArgs
36,604✔
533
        parentClosureEntityMetadata?: EntityMetadata
36,604✔
534
        args: TableMetadataArgs
36,604✔
535
    }) {
36,604✔
536
        this.connection = options.connection
36,604✔
537
        this.inheritanceTree = options.inheritanceTree || []
36,604✔
538
        this.inheritancePattern = options.inheritancePattern
36,604✔
539
        this.treeType = options.tableTree ? options.tableTree.type : undefined
36,604✔
540
        this.treeOptions = options.tableTree
36,604✔
541
            ? options.tableTree.options
36,604!
542
            : undefined
36,604✔
543
        this.parentClosureEntityMetadata = options.parentClosureEntityMetadata!
36,604✔
544
        this.tableMetadataArgs = options.args
36,604✔
545
        this.target = this.tableMetadataArgs.target
36,604✔
546
        this.tableType = this.tableMetadataArgs.type
36,604✔
547
        this.expression = this.tableMetadataArgs.expression
36,604✔
548
        this.withoutRowid = this.tableMetadataArgs.withoutRowid
36,604✔
549
        this.dependsOn = this.tableMetadataArgs.dependsOn
36,604✔
550
    }
36,604✔
551

26✔
552
    // -------------------------------------------------------------------------
26✔
553
    // Public Methods
26✔
554
    // -------------------------------------------------------------------------
26✔
555

26✔
556
    /**
26✔
557
     * Creates a new entity.
26✔
558
     */
26✔
559
    create(
26✔
560
        queryRunner?: QueryRunner,
602,871✔
561
        options?: { fromDeserializer?: boolean; pojo?: boolean },
602,871✔
562
    ): any {
602,871✔
563
        const pojo = options && options.pojo === true ? true : false
602,871!
564
        // if target is set to a function (e.g. class) that can be created then create it
602,871✔
565
        let ret: any
602,871✔
566
        if (typeof this.target === "function" && !pojo) {
602,871✔
567
            if (!options?.fromDeserializer || this.isAlwaysUsingConstructor) {
589,169✔
568
                ret = new (<any>this.target)()
589,135✔
569
            } else {
589,169!
570
                ret = Object.create(this.target.prototype)
34✔
571
            }
34✔
572
        } else {
602,871✔
573
            // otherwise simply return a new empty object
13,702✔
574
            ret = {}
13,702✔
575
        }
13,702✔
576

602,847✔
577
        // add "typename" property
602,847✔
578
        if (this.connection.options.typename) {
602,871!
579
            ret[this.connection.options.typename] = this.targetName
×
580
        }
×
581

602,847✔
582
        this.lazyRelations.forEach((relation) =>
602,847✔
583
            this.connection.relationLoader.enableLazyLoad(
4,002✔
584
                relation,
4,002✔
585
                ret,
4,002✔
586
                queryRunner,
4,002✔
587
            ),
602,847✔
588
        )
602,847✔
589
        return ret
602,847✔
590
    }
602,847✔
591

26✔
592
    /**
26✔
593
     * Checks if given entity has an id.
26✔
594
     */
26✔
595
    hasId(entity: ObjectLiteral): boolean {
26✔
596
        if (!entity) return false
366!
597

310✔
598
        return this.primaryColumns.every((primaryColumn) => {
310✔
599
            const value = primaryColumn.getEntityValue(entity)
310✔
600
            return value !== null && value !== undefined && value !== ""
310✔
601
        })
310✔
602
    }
310✔
603

26✔
604
    /**
26✔
605
     * Checks if given entity / object contains ALL primary keys entity must have.
26✔
606
     * Returns true if it contains all of them, false if at least one of them is not defined.
26✔
607
     */
26✔
608
    hasAllPrimaryKeys(entity: ObjectLiteral): boolean {
26✔
609
        return this.primaryColumns.every((primaryColumn) => {
90✔
610
            const value = primaryColumn.getEntityValue(entity)
90✔
611
            return value !== null && value !== undefined
90✔
612
        })
90✔
613
    }
90✔
614

26✔
615
    /**
26✔
616
     * Ensures that given object is an entity id map.
26✔
617
     * If given id is an object then it means its already id map.
26✔
618
     * If given id isn't an object then it means its a value of the id column
26✔
619
     * and it creates a new id map with this value and name of the primary column.
26✔
620
     */
26✔
621
    ensureEntityIdMap(id: any): ObjectLiteral {
26✔
622
        if (ObjectUtils.isObject(id)) return id
206,445✔
623

1,264✔
624
        if (this.hasMultiplePrimaryKeys)
1,264✔
625
            throw new CannotCreateEntityIdMapError(this, id)
206,445!
626

1,264✔
627
        return this.primaryColumns[0].createValueMap(id)
1,264✔
628
    }
1,264✔
629

26✔
630
    /**
26✔
631
     * Gets primary keys of the entity and returns them in a literal object.
26✔
632
     * For example, for Post{ id: 1, title: "hello" } where id is primary it will return { id: 1 }
26✔
633
     * For multiple primary keys it returns multiple keys in object.
26✔
634
     * For primary keys inside embeds it returns complex object literal with keys in them.
26✔
635
     */
26✔
636
    getEntityIdMap(
26✔
637
        entity: ObjectLiteral | undefined,
1,572,976✔
638
    ): ObjectLiteral | undefined {
1,572,976✔
639
        if (!entity) return undefined
1,572,976!
640

1,570,341✔
641
        return EntityMetadata.getValueMap(entity, this.primaryColumns, {
1,570,341✔
642
            skipNulls: true,
1,570,341✔
643
        })
1,570,341✔
644
    }
1,570,341✔
645

26✔
646
    /**
26✔
647
     * Creates a "mixed id map".
26✔
648
     * If entity has multiple primary keys (ids) then it will return just regular id map, like what getEntityIdMap returns.
26✔
649
     * But if entity has a single primary key then it will return just value of the id column of the entity, just value.
26✔
650
     * This is called mixed id map.
26✔
651
     */
26✔
652
    getEntityIdMixedMap(
26✔
653
        entity: ObjectLiteral | undefined,
9,956✔
654
    ): ObjectLiteral | undefined {
9,956✔
655
        if (!entity) return entity
9,956!
656

4,411✔
657
        const idMap = this.getEntityIdMap(entity)
4,411✔
658
        if (this.hasMultiplePrimaryKeys) {
9,956!
659
            return idMap
228✔
660
        } else if (idMap) {
9,956✔
661
            return this.primaryColumns[0].getEntityValue(idMap) // todo: what about parent primary column?
4,183✔
662
        }
4,183✔
663

×
664
        return idMap
×
665
    }
×
666

26✔
667
    /**
26✔
668
     * Compares two different entities by their ids.
26✔
669
     * Returns true if they match, false otherwise.
26✔
670
     */
26✔
671
    compareEntities(
26✔
672
        firstEntity: ObjectLiteral,
74,630✔
673
        secondEntity: ObjectLiteral,
74,630✔
674
    ): boolean {
74,630✔
675
        const firstEntityIdMap = this.getEntityIdMap(firstEntity)
74,630✔
676
        if (!firstEntityIdMap) return false
74,630!
677

4,106✔
678
        const secondEntityIdMap = this.getEntityIdMap(secondEntity)
4,106✔
679
        if (!secondEntityIdMap) return false
74,630!
680

3,254✔
681
        return OrmUtils.compareIds(firstEntityIdMap, secondEntityIdMap)
3,254✔
682
    }
3,254✔
683

26✔
684
    /**
26✔
685
     * Finds column with a given property name.
26✔
686
     */
26✔
687
    findColumnWithPropertyName(
26✔
688
        propertyName: string,
656✔
689
    ): ColumnMetadata | undefined {
656✔
690
        return this.columns.find(
656✔
691
            (column) => column.propertyName === propertyName,
656✔
692
        )
656✔
693
    }
656✔
694

26✔
695
    /**
26✔
696
     * Finds column with a given database name.
26✔
697
     */
26✔
698
    findColumnWithDatabaseName(
26✔
699
        databaseName: string,
219,937✔
700
    ): ColumnMetadata | undefined {
219,937✔
701
        return this.columns.find(
219,937✔
702
            (column) => column.databaseName === databaseName,
219,937✔
703
        )
219,937✔
704
    }
219,937✔
705

26✔
706
    /**
26✔
707
     * Checks if there is a column or relationship with a given property path.
26✔
708
     */
26✔
709
    hasColumnWithPropertyPath(propertyPath: string): boolean {
26✔
710
        const hasColumn = this.columns.some(
×
711
            (column) => column.propertyPath === propertyPath,
×
712
        )
×
713
        return hasColumn || this.hasRelationWithPropertyPath(propertyPath)
×
714
    }
×
715

26✔
716
    /**
26✔
717
     * Finds column with a given property path.
26✔
718
     */
26✔
719
    findColumnWithPropertyPath(
26✔
720
        propertyPath: string,
2,094✔
721
    ): ColumnMetadata | undefined {
2,094✔
722
        const column = this.columns.find(
2,094✔
723
            (column) => column.propertyPath === propertyPath,
2,094✔
724
        )
2,094✔
725
        if (column) return column
2,094✔
726

56✔
727
        // in the case if column with property path was not found, try to find a relation with such property path
56✔
728
        // if we find relation and it has a single join column then its the column user was seeking
56✔
729
        const relation = this.relations.find(
56✔
730
            (relation) => relation.propertyPath === propertyPath,
56✔
731
        )
56✔
732
        if (relation && relation.joinColumns.length === 1)
2,094!
733
            return relation.joinColumns[0]
2,094!
734

56✔
735
        return undefined
56✔
736
    }
56✔
737

26✔
738
    /**
26✔
739
     * Finds column with a given property path.
26✔
740
     * Does not search in relation unlike findColumnWithPropertyPath.
26✔
741
     */
26✔
742
    findColumnWithPropertyPathStrict(
26✔
743
        propertyPath: string,
68,523✔
744
    ): ColumnMetadata | undefined {
68,523✔
745
        return this.columns.find(
68,523✔
746
            (column) => column.propertyPath === propertyPath,
68,523✔
747
        )
68,523✔
748
    }
68,523✔
749

26✔
750
    /**
26✔
751
     * Finds columns with a given property path.
26✔
752
     * Property path can match a relation, and relations can contain multiple columns.
26✔
753
     */
26✔
754
    findColumnsWithPropertyPath(propertyPath: string): ColumnMetadata[] {
26✔
755
        const column = this.columns.find(
199,570✔
756
            (column) => column.propertyPath === propertyPath,
199,570✔
757
        )
199,570✔
758
        if (column) return [column]
199,570✔
759

9,286✔
760
        // in the case if column with property path was not found, try to find a relation with such property path
9,286✔
761
        // if we find relation and it has a single join column then its the column user was seeking
9,286✔
762
        const relation = this.findRelationWithPropertyPath(propertyPath)
9,286✔
763
        if (relation && relation.joinColumns) return relation.joinColumns
199,570✔
764

140✔
765
        return []
140✔
766
    }
140✔
767

26✔
768
    /**
26✔
769
     * Checks if there is a relation with the given property path.
26✔
770
     */
26✔
771
    hasRelationWithPropertyPath(propertyPath: string): boolean {
26✔
772
        return this.relations.some(
8,882✔
773
            (relation) => relation.propertyPath === propertyPath,
8,882✔
774
        )
8,882✔
775
    }
8,882✔
776

26✔
777
    /**
26✔
778
     * Finds relation with the given property path.
26✔
779
     */
26✔
780
    findRelationWithPropertyPath(
26✔
781
        propertyPath: string,
3,888,678✔
782
    ): RelationMetadata | undefined {
3,888,678✔
783
        return this.relations.find(
3,888,678✔
784
            (relation) => relation.propertyPath === propertyPath,
3,888,678✔
785
        )
3,888,678✔
786
    }
3,888,678✔
787

26✔
788
    /**
26✔
789
     * Checks if there is an embedded with a given property path.
26✔
790
     */
26✔
791
    hasEmbeddedWithPropertyPath(propertyPath: string): boolean {
26✔
792
        return this.allEmbeddeds.some(
21,282✔
793
            (embedded) => embedded.propertyPath === propertyPath,
21,282✔
794
        )
21,282✔
795
    }
21,282✔
796

26✔
797
    /**
26✔
798
     * Finds embedded with a given property path.
26✔
799
     */
26✔
800
    findEmbeddedWithPropertyPath(
26✔
801
        propertyPath: string,
806,315✔
802
    ): EmbeddedMetadata | undefined {
806,315✔
803
        return this.allEmbeddeds.find(
806,315✔
804
            (embedded) => embedded.propertyPath === propertyPath,
806,315✔
805
        )
806,315✔
806
    }
806,315✔
807

26✔
808
    /**
26✔
809
     * Returns an array of databaseNames mapped from provided propertyPaths
26✔
810
     */
26✔
811
    mapPropertyPathsToColumns(propertyPaths: string[]) {
26✔
812
        return propertyPaths.map((propertyPath) => {
578✔
813
            const column = this.findColumnWithPropertyPath(propertyPath)
582✔
814
            if (column == null) {
582!
815
                throw new EntityPropertyNotFoundError(propertyPath, this)
×
816
            }
×
817
            return column
582✔
818
        })
578✔
819
    }
578✔
820

26✔
821
    /**
26✔
822
     * Iterates through entity and finds and extracts all values from relations in the entity.
26✔
823
     * If relation value is an array its being flattened.
26✔
824
     */
26✔
825
    extractRelationValuesFromEntity(
26✔
826
        entity: ObjectLiteral,
442,307✔
827
        relations: RelationMetadata[],
442,307✔
828
    ): [RelationMetadata, any, EntityMetadata][] {
442,307✔
829
        const relationsAndValues: [RelationMetadata, any, EntityMetadata][] = []
442,307✔
830
        relations.forEach((relation) => {
442,307✔
831
            const value = relation.getEntityValue(entity)
185,673✔
832
            if (Array.isArray(value)) {
185,673✔
833
                value.forEach((subValue) =>
36,994✔
834
                    relationsAndValues.push([
71,880✔
835
                        relation,
71,880✔
836
                        subValue,
71,880✔
837
                        EntityMetadata.getInverseEntityMetadata(
71,880✔
838
                            subValue,
71,880✔
839
                            relation,
71,880✔
840
                        ),
71,880✔
841
                    ]),
36,994✔
842
                )
36,994✔
843
            } else if (value) {
185,673✔
844
                relationsAndValues.push([
23,289✔
845
                    relation,
23,289✔
846
                    value,
23,289✔
847
                    EntityMetadata.getInverseEntityMetadata(value, relation),
23,289✔
848
                ])
23,289✔
849
            }
23,289✔
850
        })
442,307✔
851
        return relationsAndValues
442,307✔
852
    }
442,307✔
853

26✔
854
    /**
26✔
855
     * In the case of SingleTableInheritance, find the correct metadata
26✔
856
     * for a given value.
26✔
857
     *
26✔
858
     * @param value The value to find the metadata for.
26✔
859
     * @returns The found metadata for the entity or the base metadata if no matching metadata
26✔
860
     *          was found in the whole inheritance tree.
26✔
861
     */
26✔
862
    findInheritanceMetadata(value: any): EntityMetadata {
26✔
863
        // Check for single table inheritance and find the correct metadata in that case.
497,753✔
864
        // Goal is to use the correct discriminator as we could have a repository
497,753✔
865
        // for an (abstract) base class and thus the target would not match.
497,753✔
866

497,753✔
867
        if (
497,753✔
868
            this.inheritancePattern === "STI" &&
497,753!
869
            this.childEntityMetadatas.length > 0
2,145✔
870
        ) {
497,753!
871
            // There could be a column on the base class that can manually be set to override the type.
810✔
872
            let manuallySetDiscriminatorValue: unknown
810✔
873
            if (this.discriminatorColumn) {
810✔
874
                manuallySetDiscriminatorValue =
810✔
875
                    value[this.discriminatorColumn.propertyName]
810✔
876
            }
810✔
877
            return (
810✔
878
                this.childEntityMetadatas.find(
810✔
879
                    (meta) =>
810✔
880
                        manuallySetDiscriminatorValue ===
1,256✔
881
                            meta.discriminatorValue ||
1,256✔
882
                        value.constructor === meta.target,
810✔
883
                ) || this
810✔
884
            )
810✔
885
        }
810✔
886
        return this
496,943✔
887
    }
496,943✔
888

26✔
889
    // -------------------------------------------------------------------------
26✔
890
    // Private Static Methods
26✔
891
    // -------------------------------------------------------------------------
26✔
892

26✔
893
    private static getInverseEntityMetadata(
26✔
894
        value: any,
95,169✔
895
        relation: RelationMetadata,
95,169✔
896
    ): EntityMetadata {
95,169✔
897
        return relation.inverseEntityMetadata.findInheritanceMetadata(value)
95,169✔
898
    }
95,169✔
899

26✔
900
    // -------------------------------------------------------------------------
26✔
901
    // Public Static Methods
26✔
902
    // -------------------------------------------------------------------------
26✔
903

26✔
904
    /**
26✔
905
     * Creates a property paths for a given entity.
26✔
906
     *
26✔
907
     * @deprecated
26✔
908
     */
26✔
909
    static createPropertyPath(
26✔
910
        metadata: EntityMetadata,
×
911
        entity: ObjectLiteral,
×
912
        prefix: string = "",
×
913
    ) {
×
914
        const paths: string[] = []
×
915
        Object.keys(entity).forEach((key) => {
×
916
            // check for function is needed in the cases when createPropertyPath used on values contain a function as a value
×
917
            // example: .update().set({ name: () => `SUBSTR('', 1, 2)` })
×
918
            const parentPath = prefix ? prefix + "." + key : key
×
919
            if (metadata.hasEmbeddedWithPropertyPath(parentPath)) {
×
920
                const subPaths = this.createPropertyPath(
×
921
                    metadata,
×
922
                    entity[key],
×
923
                    parentPath,
×
924
                )
×
925
                paths.push(...subPaths)
×
926
            } else {
×
927
                const path = prefix ? prefix + "." + key : key
×
928
                paths.push(path)
×
929
            }
×
930
        })
×
931
        return paths
×
932
    }
×
933

26✔
934
    /**
26✔
935
     * Finds difference between two entity id maps.
26✔
936
     * Returns items that exist in the first array and absent in the second array.
26✔
937
     */
26✔
938
    static difference(
26✔
939
        firstIdMaps: ObjectLiteral[],
13,476✔
940
        secondIdMaps: ObjectLiteral[],
13,476✔
941
    ): ObjectLiteral[] {
13,476✔
942
        return firstIdMaps.filter((firstIdMap) => {
13,476✔
943
            return !secondIdMaps.find((secondIdMap) =>
1,298✔
944
                OrmUtils.compareIds(firstIdMap, secondIdMap),
1,298✔
945
            )
1,298✔
946
        })
13,476✔
947
    }
13,476✔
948

26✔
949
    /**
26✔
950
     * Creates value map from the given values and columns.
26✔
951
     * Examples of usages are primary columns map and join columns map.
26✔
952
     */
26✔
953
    static getValueMap(
26✔
954
        entity: ObjectLiteral,
1,611,355✔
955
        columns: ColumnMetadata[],
1,611,355✔
956
        options?: { skipNulls?: boolean },
1,611,355✔
957
    ): ObjectLiteral | undefined {
1,611,355✔
958
        return columns.reduce((map, column) => {
1,611,355✔
959
            const value = column.getEntityValueMap(entity, options)
1,733,460✔
960

1,733,460✔
961
            // make sure that none of the values of the columns are not missing
1,733,460✔
962
            if (map === undefined || value === null || value === undefined)
1,733,460✔
963
                return undefined
1,733,460✔
964

1,343,891✔
965
            return OrmUtils.mergeDeep(map, value)
1,343,891✔
966
        }, {} as ObjectLiteral | undefined)
1,611,355✔
967
    }
1,611,355✔
968

26✔
969
    // ---------------------------------------------------------------------
26✔
970
    // Public Builder Methods
26✔
971
    // ---------------------------------------------------------------------
26✔
972

26✔
973
    build() {
26✔
974
        const namingStrategy = this.connection.namingStrategy
36,604✔
975
        const entityPrefix = this.connection.options.entityPrefix
36,604✔
976
        const entitySkipConstructor =
36,604✔
977
            this.connection.options.entitySkipConstructor
36,604✔
978

36,604✔
979
        this.engine = this.tableMetadataArgs.engine
36,604✔
980
        this.database =
36,604✔
981
            this.tableMetadataArgs.type === "entity-child" &&
36,604!
982
            this.parentEntityMetadata
1,409✔
983
                ? this.parentEntityMetadata.database
36,604!
984
                : this.tableMetadataArgs.database
36,604✔
985
        if (this.tableMetadataArgs.schema) {
36,604!
986
            this.schema = this.tableMetadataArgs.schema
69✔
987
        } else if (
36,604✔
988
            this.tableMetadataArgs.type === "entity-child" &&
36,535!
989
            this.parentEntityMetadata
1,409✔
990
        ) {
36,535!
991
            this.schema = this.parentEntityMetadata.schema
1,409✔
992
        } else if (this.connection.options?.hasOwnProperty("schema")) {
36,535!
993
            this.schema = (this.connection.options as any).schema
65✔
994
        }
65✔
995
        this.givenTableName =
36,604✔
996
            this.tableMetadataArgs.type === "entity-child" &&
36,604!
997
            this.parentEntityMetadata
1,409✔
998
                ? this.parentEntityMetadata.givenTableName
36,604!
999
                : this.tableMetadataArgs.name
36,604✔
1000
        this.synchronize =
36,604✔
1001
            this.tableMetadataArgs.synchronize === false ? false : true
36,604!
1002
        this.targetName =
36,604✔
1003
            typeof this.tableMetadataArgs.target === "function"
36,604✔
1004
                ? (this.tableMetadataArgs.target as any).name
36,604✔
1005
                : this.tableMetadataArgs.target
36,604✔
1006
        if (this.tableMetadataArgs.type === "closure-junction") {
36,604!
1007
            this.tableNameWithoutPrefix =
544✔
1008
                namingStrategy.closureJunctionTableName(this.givenTableName!)
544✔
1009
        } else if (
36,604✔
1010
            this.tableMetadataArgs.type === "entity-child" &&
36,060!
1011
            this.parentEntityMetadata
1,409✔
1012
        ) {
36,060!
1013
            this.tableNameWithoutPrefix = namingStrategy.tableName(
1,409✔
1014
                this.parentEntityMetadata.targetName,
1,409✔
1015
                this.parentEntityMetadata.givenTableName,
1,409✔
1016
            )
1,409✔
1017
        } else {
36,060✔
1018
            this.tableNameWithoutPrefix = namingStrategy.tableName(
34,651✔
1019
                this.targetName,
34,651✔
1020
                this.givenTableName,
34,651✔
1021
            )
34,651✔
1022

34,651✔
1023
            if (
34,651✔
1024
                this.tableMetadataArgs.type === "junction" &&
34,651✔
1025
                this.connection.driver.maxAliasLength &&
34,651✔
1026
                this.connection.driver.maxAliasLength > 0 &&
34,651✔
1027
                this.tableNameWithoutPrefix.length >
2,142✔
1028
                    this.connection.driver.maxAliasLength
2,142✔
1029
            ) {
34,651!
1030
                // note: we are not using DriverUtils.buildAlias here because we would like to avoid
38✔
1031
                // hashed table names. However, current algorithm also isn't perfect, but we cannot
38✔
1032
                // change it, since it's a big breaking change. Planned to 0.4.0
38✔
1033
                this.tableNameWithoutPrefix = shorten(
38✔
1034
                    this.tableNameWithoutPrefix,
38✔
1035
                    { separator: "_", segmentLength: 3 },
38✔
1036
                )
38✔
1037
            }
38✔
1038
        }
34,651✔
1039
        this.tableName = entityPrefix
36,604✔
1040
            ? namingStrategy.prefixTableName(
36,604!
1041
                  entityPrefix,
×
1042
                  this.tableNameWithoutPrefix,
×
1043
              )
36,604✔
1044
            : this.tableNameWithoutPrefix
36,604✔
1045
        this.target = this.target ? this.target : this.tableName
36,604✔
1046
        this.name = this.targetName ? this.targetName : this.tableName
36,604✔
1047
        this.expression = this.tableMetadataArgs.expression
36,604✔
1048
        this.withoutRowid =
36,604✔
1049
            this.tableMetadataArgs.withoutRowid === true ? true : false
36,604!
1050
        this.tablePath = this.connection.driver.buildTableName(
36,604✔
1051
            this.tableName,
36,604✔
1052
            this.schema,
36,604✔
1053
            this.database,
36,604✔
1054
        )
36,604✔
1055
        this.orderBy =
36,604✔
1056
            typeof this.tableMetadataArgs.orderBy === "function"
36,604✔
1057
                ? this.tableMetadataArgs.orderBy(this.propertiesMap)
36,604!
1058
                : this.tableMetadataArgs.orderBy // todo: is propertiesMap available here? Looks like its not
36,604✔
1059

36,604✔
1060
        if (entitySkipConstructor !== undefined) {
36,604!
1061
            this.isAlwaysUsingConstructor = !entitySkipConstructor
55✔
1062
        }
55✔
1063

36,604✔
1064
        this.isJunction =
36,604✔
1065
            this.tableMetadataArgs.type === "closure-junction" ||
36,604✔
1066
            this.tableMetadataArgs.type === "junction"
36,060✔
1067
        this.isClosureJunction =
36,604✔
1068
            this.tableMetadataArgs.type === "closure-junction"
36,604✔
1069

36,604✔
1070
        this.comment = this.tableMetadataArgs.comment
36,604✔
1071
    }
36,604✔
1072

26✔
1073
    /**
26✔
1074
     * Registers a new column in the entity and recomputes all depend properties.
26✔
1075
     */
26✔
1076
    registerColumn(column: ColumnMetadata) {
26✔
1077
        if (this.ownColumns.indexOf(column) !== -1) return
10,427!
1078

10,423✔
1079
        this.ownColumns.push(column)
10,423✔
1080
        this.columns = this.embeddeds.reduce(
10,423✔
1081
            (columns, embedded) => columns.concat(embedded.columnsFromTree),
10,423✔
1082
            this.ownColumns,
10,423✔
1083
        )
10,423✔
1084
        this.primaryColumns = this.columns.filter((column) => column.isPrimary)
10,423✔
1085
        this.hasMultiplePrimaryKeys = this.primaryColumns.length > 1
10,423✔
1086
        this.hasUUIDGeneratedColumns =
10,423✔
1087
            this.columns.filter(
10,423✔
1088
                (column) =>
10,423✔
1089
                    column.isGenerated || column.generationStrategy === "uuid",
10,423✔
1090
            ).length > 0
10,423✔
1091
        this.propertiesMap = this.createPropertiesMap()
10,423✔
1092
        if (this.childEntityMetadatas)
10,423✔
1093
            this.childEntityMetadatas.forEach((entityMetadata) =>
10,423✔
1094
                entityMetadata.registerColumn(column),
10,423✔
1095
            )
10,423✔
1096
    }
10,427✔
1097

26✔
1098
    /**
26✔
1099
     * Creates a special object - all columns and relations of the object (plus columns and relations from embeds)
26✔
1100
     * in a special format - { propertyName: propertyName }.
26✔
1101
     *
26✔
1102
     * example: Post{ id: number, name: string, counterEmbed: { count: number }, category: Category }.
26✔
1103
     * This method will create following object:
26✔
1104
     * { id: "id", counterEmbed: { count: "counterEmbed.count" }, category: "category" }
26✔
1105
     */
26✔
1106
    createPropertiesMap(): { [name: string]: string | any } {
26✔
1107
        const map: { [name: string]: string | any } = {}
71,720✔
1108
        this.columns.forEach((column) =>
71,720✔
1109
            OrmUtils.mergeDeep(map, column.createValueMap(column.propertyPath)),
71,720✔
1110
        )
71,720✔
1111
        this.relations.forEach((relation) =>
71,720✔
1112
            OrmUtils.mergeDeep(
69,633✔
1113
                map,
69,633✔
1114
                relation.createValueMap(relation.propertyPath),
69,633✔
1115
            ),
71,720✔
1116
        )
71,720✔
1117
        return map
71,720✔
1118
    }
71,720✔
1119

26✔
1120
    /**
26✔
1121
     * Checks if entity has any column which rely on returning data,
26✔
1122
     * e.g. columns with auto generated value, DEFAULT values considered as dependant of returning data.
26✔
1123
     * For example, if we need to have RETURNING after INSERT (or we need returned id for DBs not supporting RETURNING),
26✔
1124
     * it means we cannot execute bulk inserts in some cases.
26✔
1125
     */
26✔
1126
    getInsertionReturningColumns(): ColumnMetadata[] {
26✔
1127
        return this.columns.filter((column) => {
739,697✔
1128
            return (
2,473,138✔
1129
                column.default !== undefined ||
2,473,138✔
1130
                column.asExpression !== undefined ||
2,473,138✔
1131
                column.isGenerated ||
2,473,138✔
1132
                column.isCreateDate ||
2,473,138✔
1133
                column.isUpdateDate ||
2,473,138✔
1134
                column.isDeleteDate ||
2,473,138✔
1135
                column.isVersion
2,144,341✔
1136
            )
2,473,138✔
1137
        })
739,697✔
1138
    }
739,697✔
1139
}
26✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc