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

typeorm / typeorm / 15219332477

23 May 2025 09:13PM UTC coverage: 17.216% (-59.1%) from 76.346%
15219332477

Pull #11332

github

naorpeled
cr comments - move if block
Pull Request #11332: feat: add new undefined and null behavior flags

1603 of 12759 branches covered (12.56%)

Branch coverage included in aggregate %.

0 of 31 new or added lines in 3 files covered. (0.0%)

14132 existing lines in 166 files now uncovered.

4731 of 24033 relevant lines covered (19.69%)

60.22 hits per line

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

2.94
/src/query-builder/RelationRemover.ts
1
import { QueryBuilder } from "./QueryBuilder"
2
import { ObjectLiteral } from "../common/ObjectLiteral"
3
import { QueryExpressionMap } from "./QueryExpressionMap"
4
import { ObjectUtils } from "../util/ObjectUtils"
1✔
5

6
/**
7
 * Allows to work with entity relations and perform specific operations with those relations.
8
 *
9
 * todo: add transactions everywhere
10
 */
11
export class RelationRemover {
1✔
12
    // -------------------------------------------------------------------------
13
    // Constructor
14
    // -------------------------------------------------------------------------
15

16
    constructor(
UNCOV
17
        protected queryBuilder: QueryBuilder<any>,
×
UNCOV
18
        protected expressionMap: QueryExpressionMap,
×
19
    ) {}
20

21
    // -------------------------------------------------------------------------
22
    // Public Methods
23
    // -------------------------------------------------------------------------
24

25
    /**
26
     * Performs remove operation on a relation.
27
     */
28
    async remove(value: any | any[]): Promise<void> {
UNCOV
29
        const relation = this.expressionMap.relationMetadata
×
30

UNCOV
31
        if (relation.isOneToMany) {
×
32
            // if (this.expressionMap.of instanceof Array)
33
            //     throw new TypeORMError(`You cannot update relations of multiple entities with the same related object. Provide a single entity into .of method.`);
34

35
            // DELETE FROM post WHERE post.categoryId = of AND post.id = id
UNCOV
36
            const ofs = Array.isArray(this.expressionMap.of)
×
37
                ? this.expressionMap.of
38
                : [this.expressionMap.of]
UNCOV
39
            const values = Array.isArray(value) ? value : [value]
×
40

UNCOV
41
            const updateSet: ObjectLiteral = {}
×
UNCOV
42
            relation.inverseRelation!.joinColumns.forEach((column) => {
×
UNCOV
43
                updateSet[column.propertyName] = null
×
44
            })
45

UNCOV
46
            const parameters: ObjectLiteral = {}
×
UNCOV
47
            const conditions: string[] = []
×
UNCOV
48
            ofs.forEach((of, ofIndex) => {
×
UNCOV
49
                conditions.push(
×
50
                    ...values.map((value, valueIndex) => {
UNCOV
51
                        return [
×
52
                            ...relation.inverseRelation!.joinColumns.map(
53
                                (column, columnIndex) => {
54
                                    const parameterName =
UNCOV
55
                                        "joinColumn_" +
×
56
                                        ofIndex +
57
                                        "_" +
58
                                        valueIndex +
59
                                        "_" +
60
                                        columnIndex
UNCOV
61
                                    parameters[parameterName] =
×
62
                                        ObjectUtils.isObject(of)
×
63
                                            ? column.referencedColumn!.getEntityValue(
64
                                                  of,
65
                                              )
66
                                            : of
UNCOV
67
                                    return `${column.propertyPath} = :${parameterName}`
×
68
                                },
69
                            ),
70
                            ...relation.inverseRelation!.entityMetadata.primaryColumns.map(
71
                                (column, columnIndex) => {
72
                                    const parameterName =
UNCOV
73
                                        "primaryColumn_" +
×
74
                                        valueIndex +
75
                                        "_" +
76
                                        valueIndex +
77
                                        "_" +
78
                                        columnIndex
UNCOV
79
                                    parameters[parameterName] =
×
80
                                        ObjectUtils.isObject(value)
×
81
                                            ? column.getEntityValue(value)
82
                                            : value
UNCOV
83
                                    return `${column.propertyPath} = :${parameterName}`
×
84
                                },
85
                            ),
86
                        ].join(" AND ")
87
                    }),
88
                )
89
            })
UNCOV
90
            const condition = conditions
×
UNCOV
91
                .map((str) => "(" + str + ")")
×
92
                .join(" OR ")
UNCOV
93
            if (!condition) return
×
94

UNCOV
95
            await this.queryBuilder
×
96
                .createQueryBuilder()
97
                .update(relation.inverseEntityMetadata.target)
98
                .set(updateSet)
99
                .where(condition)
100
                .setParameters(parameters)
101
                .execute()
102
        } else {
103
            // many to many
104

UNCOV
105
            const junctionMetadata = relation.junctionEntityMetadata!
×
UNCOV
106
            const ofs = Array.isArray(this.expressionMap.of)
×
107
                ? this.expressionMap.of
108
                : [this.expressionMap.of]
UNCOV
109
            const values = Array.isArray(value) ? value : [value]
×
UNCOV
110
            const firstColumnValues = relation.isManyToManyOwner ? ofs : values
×
UNCOV
111
            const secondColumnValues = relation.isManyToManyOwner ? values : ofs
×
112

UNCOV
113
            const parameters: ObjectLiteral = {}
×
UNCOV
114
            const conditions: string[] = []
×
UNCOV
115
            firstColumnValues.forEach((firstColumnVal, firstColumnValIndex) => {
×
UNCOV
116
                conditions.push(
×
117
                    ...secondColumnValues.map(
118
                        (secondColumnVal, secondColumnValIndex) => {
UNCOV
119
                            return [
×
120
                                ...junctionMetadata.ownerColumns.map(
121
                                    (column, columnIndex) => {
122
                                        const parameterName =
UNCOV
123
                                            "firstValue_" +
×
124
                                            firstColumnValIndex +
125
                                            "_" +
126
                                            secondColumnValIndex +
127
                                            "_" +
128
                                            columnIndex
UNCOV
129
                                        parameters[parameterName] =
×
130
                                            ObjectUtils.isObject(firstColumnVal)
×
131
                                                ? column.referencedColumn!.getEntityValue(
132
                                                      firstColumnVal,
133
                                                  )
134
                                                : firstColumnVal
UNCOV
135
                                        return `${column.databaseName} = :${parameterName}`
×
136
                                    },
137
                                ),
138
                                ...junctionMetadata.inverseColumns.map(
139
                                    (column, columnIndex) => {
140
                                        const parameterName =
UNCOV
141
                                            "secondValue_" +
×
142
                                            firstColumnValIndex +
143
                                            "_" +
144
                                            secondColumnValIndex +
145
                                            "_" +
146
                                            columnIndex
UNCOV
147
                                        parameters[parameterName] =
×
148
                                            ObjectUtils.isObject(
×
149
                                                secondColumnVal,
150
                                            )
151
                                                ? column.referencedColumn!.getEntityValue(
152
                                                      secondColumnVal,
153
                                                  )
154
                                                : secondColumnVal
UNCOV
155
                                        return `${column.databaseName} = :${parameterName}`
×
156
                                    },
157
                                ),
158
                            ].join(" AND ")
159
                        },
160
                    ),
161
                )
162
            })
UNCOV
163
            const condition = conditions
×
UNCOV
164
                .map((str) => "(" + str + ")")
×
165
                .join(" OR ")
166

UNCOV
167
            await this.queryBuilder
×
168
                .createQueryBuilder()
169
                .delete()
170
                .from(junctionMetadata.tableName)
171
                .where(condition)
172
                .setParameters(parameters)
173
                .execute()
174
        }
175
    }
176
}
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

© 2025 Coveralls, Inc