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

typeorm / typeorm / 15089093306

17 May 2025 09:03PM UTC coverage: 50.109% (-26.2%) from 76.346%
15089093306

Pull #11437

github

naorpeled
add comment about vector <#>
Pull Request #11437: feat(postgres): support vector data type

5836 of 12767 branches covered (45.71%)

Branch coverage included in aggregate %.

16 of 17 new or added lines in 4 files covered. (94.12%)

6283 existing lines in 64 files now uncovered.

12600 of 24025 relevant lines covered (52.45%)

28708.0 hits per line

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

89.72
/src/query-builder/RelationUpdater.ts
1
import { QueryBuilder } from "./QueryBuilder"
2
import { ObjectLiteral } from "../common/ObjectLiteral"
3
import { QueryExpressionMap } from "./QueryExpressionMap"
4
import { TypeORMError } from "../error"
6✔
5
import { ObjectUtils } from "../util/ObjectUtils"
6✔
6

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

17
    constructor(
18
        protected queryBuilder: QueryBuilder<any>,
240✔
19
        protected expressionMap: QueryExpressionMap,
240✔
20
    ) {}
21

22
    // -------------------------------------------------------------------------
23
    // Public Methods
24
    // -------------------------------------------------------------------------
25

26
    /**
27
     * Performs set or add operation on a relation.
28
     */
29
    async update(value: any | any[]): Promise<void> {
30
        const relation = this.expressionMap.relationMetadata
240✔
31

32
        if (relation.isManyToOne || relation.isOneToOneOwner) {
240✔
33
            const updateSet = relation.joinColumns.reduce(
90✔
34
                (updateSet, joinColumn) => {
35
                    const relationValue = ObjectUtils.isObject(value)
90✔
36
                        ? joinColumn.referencedColumn!.getEntityValue(value)
37
                        : value
38
                    joinColumn.setEntityValue(updateSet, relationValue)
90✔
39
                    return updateSet
90✔
40
                },
41
                {} as any,
42
            )
43

44
            if (
90!
45
                !this.expressionMap.of ||
198✔
46
                (Array.isArray(this.expressionMap.of) &&
47
                    !this.expressionMap.of.length)
48
            )
49
                return
×
50

51
            await this.queryBuilder
90✔
52
                .createQueryBuilder()
53
                .update(relation.entityMetadata.target)
54
                .set(updateSet)
55
                .whereInIds(this.expressionMap.of)
56
                .execute()
57
        } else if (
150✔
58
            (relation.isOneToOneNotOwner || relation.isOneToMany) &&
336✔
59
            value === null
60
        ) {
61
            // we handle null a bit different way
62

63
            const updateSet: ObjectLiteral = {}
18✔
64
            relation.inverseRelation!.joinColumns.forEach((column) => {
18✔
65
                updateSet[column.propertyName] = null
18✔
66
            })
67

68
            const ofs = Array.isArray(this.expressionMap.of)
18!
69
                ? this.expressionMap.of
70
                : [this.expressionMap.of]
71
            const parameters: ObjectLiteral = {}
18✔
72
            const conditions: string[] = []
18✔
73
            ofs.forEach((of, ofIndex) => {
18✔
74
                relation.inverseRelation!.joinColumns.map(
18✔
75
                    (column, columnIndex) => {
76
                        const parameterName =
77
                            "joinColumn_" + ofIndex + "_" + columnIndex
18✔
78
                        parameters[parameterName] = ObjectUtils.isObject(of)
18✔
79
                            ? column.referencedColumn!.getEntityValue(of)
80
                            : of
81
                        conditions.push(
18✔
82
                            `${column.propertyPath} = :${parameterName}`,
83
                        )
84
                    },
85
                )
86
            })
87
            const condition = conditions
18✔
88
                .map((str) => "(" + str + ")")
18✔
89
                .join(" OR ")
90
            if (!condition) return
18!
91

92
            await this.queryBuilder
18✔
93
                .createQueryBuilder()
94
                .update(relation.inverseEntityMetadata.target)
95
                .set(updateSet)
96
                .where(condition)
97
                .setParameters(parameters)
98
                .execute()
99
        } else if (relation.isOneToOneNotOwner || relation.isOneToMany) {
132✔
100
            if (Array.isArray(this.expressionMap.of))
60!
101
                throw new TypeORMError(
×
102
                    `You cannot update relations of multiple entities with the same related object. Provide a single entity into .of method.`,
103
                )
104

105
            const of = this.expressionMap.of
60✔
106
            const updateSet = relation.inverseRelation!.joinColumns.reduce(
60✔
107
                (updateSet, joinColumn) => {
108
                    const relationValue = ObjectUtils.isObject(of)
60✔
109
                        ? joinColumn.referencedColumn!.getEntityValue(of)
110
                        : of
111
                    joinColumn.setEntityValue(updateSet, relationValue)
60✔
112
                    return updateSet
60✔
113
                },
114
                {} as any,
115
            )
116

117
            if (!value || (Array.isArray(value) && !value.length)) return
60!
118

119
            await this.queryBuilder
60✔
120
                .createQueryBuilder()
121
                .update(relation.inverseEntityMetadata.target)
122
                .set(updateSet)
123
                .whereInIds(value)
124
                .execute()
125
        } else {
126
            // many to many
127
            const junctionMetadata = relation.junctionEntityMetadata!
72✔
128
            const ofs = Array.isArray(this.expressionMap.of)
72✔
129
                ? this.expressionMap.of
130
                : [this.expressionMap.of]
131
            const values = Array.isArray(value) ? value : [value]
72✔
132
            const firstColumnValues = relation.isManyToManyOwner ? ofs : values
72✔
133
            const secondColumnValues = relation.isManyToManyOwner ? values : ofs
72✔
134

135
            const bulkInserted: ObjectLiteral[] = []
72✔
136
            firstColumnValues.forEach((firstColumnVal) => {
72✔
137
                secondColumnValues.forEach((secondColumnVal) => {
84✔
138
                    const inserted: ObjectLiteral = {}
96✔
139
                    junctionMetadata.ownerColumns.forEach((column) => {
96✔
140
                        inserted[column.databaseName] = ObjectUtils.isObject(
96✔
141
                            firstColumnVal,
142
                        )
143
                            ? column.referencedColumn!.getEntityValue(
144
                                  firstColumnVal,
145
                              )
146
                            : firstColumnVal
147
                    })
148
                    junctionMetadata.inverseColumns.forEach((column) => {
96✔
149
                        inserted[column.databaseName] = ObjectUtils.isObject(
96✔
150
                            secondColumnVal,
151
                        )
152
                            ? column.referencedColumn!.getEntityValue(
153
                                  secondColumnVal,
154
                              )
155
                            : secondColumnVal
156
                    })
157
                    bulkInserted.push(inserted)
96✔
158
                })
159
            })
160

161
            if (!bulkInserted.length) return
72!
162

163
            if (
72!
164
                this.queryBuilder.connection.driver.options.type === "oracle" ||
144✔
165
                this.queryBuilder.connection.driver.options.type === "sap"
166
            ) {
UNCOV
167
                await Promise.all(
×
168
                    bulkInserted.map((value) => {
UNCOV
169
                        return this.queryBuilder
×
170
                            .createQueryBuilder()
171
                            .insert()
172
                            .into(junctionMetadata.tableName)
173
                            .values(value)
174
                            .execute()
175
                    }),
176
                )
177
            } else {
178
                await this.queryBuilder
72✔
179
                    .createQueryBuilder()
180
                    .insert()
181
                    .into(junctionMetadata.tableName)
182
                    .values(bulkInserted)
183
                    .execute()
184
            }
185
        }
186
    }
187
}
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