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

typeorm / typeorm / 16405830134

21 Jul 2025 12:22AM UTC coverage: 76.442% (+0.002%) from 76.44%
16405830134

Pull #11576

github

web-flow
Merge ccddce2d3 into d57fe3bd8
Pull Request #11576: fix(sqlserver): queries returning multiple record sets

9324 of 12885 branches covered (72.36%)

Branch coverage included in aggregate %.

55 of 78 new or added lines in 25 files covered. (70.51%)

2073 existing lines in 24 files now uncovered.

19016 of 24189 relevant lines covered (78.61%)

119538.23 hits per line

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

86.21
/src/driver/sqlite/SqliteQueryRunner.ts
1
import { ConnectionIsNotSetError } from "../../error/ConnectionIsNotSetError"
24✔
2
import { QueryFailedError } from "../../error/QueryFailedError"
24✔
3
import { QueryRunnerAlreadyReleasedError } from "../../error/QueryRunnerAlreadyReleasedError"
24✔
4
import { QueryResult } from "../../query-runner/QueryResult"
24✔
5
import { Broadcaster } from "../../subscriber/Broadcaster"
24✔
6
import { BroadcasterResult } from "../../subscriber/BroadcasterResult"
24✔
7
import { AbstractSqliteQueryRunner } from "../sqlite-abstract/AbstractSqliteQueryRunner"
24✔
8
import { SqliteConnectionOptions } from "./SqliteConnectionOptions"
9
import { SqliteDriver } from "./SqliteDriver"
10

11
/**
12
 * Runs queries on a single sqlite database connection.
13
 *
14
 * Does not support compose primary keys with autoincrement field.
15
 * todo: need to throw exception for this case.
16
 */
17
export class SqliteQueryRunner extends AbstractSqliteQueryRunner {
24✔
18
    /**
19
     * Database driver used by connection.
20
     */
21
    driver: SqliteDriver
22

23
    // -------------------------------------------------------------------------
24
    // Constructor
25
    // -------------------------------------------------------------------------
26

27
    constructor(driver: SqliteDriver) {
28
        super()
1,467✔
29
        this.driver = driver
1,467✔
30
        this.connection = driver.connection
1,467✔
31
        this.broadcaster = new Broadcaster(this)
1,467✔
32
    }
33

34
    /**
35
     * Called before migrations are run.
36
     */
37
    async beforeMigration(): Promise<void> {
38
        await this.query(`PRAGMA foreign_keys = OFF`)
4,254✔
39
    }
40

41
    /**
42
     * Called after migrations are run.
43
     */
44
    async afterMigration(): Promise<void> {
45
        await this.query(`PRAGMA foreign_keys = ON`)
4,245✔
46
    }
47

48
    /**
49
     * Executes a given SQL query.
50
     */
51
    async query(
52
        query: string,
53
        parameters?: any[],
54
        useStructuredResult = false,
169,146✔
55
    ): Promise<any> {
56
        if (this.isReleased) throw new QueryRunnerAlreadyReleasedError()
220,947!
57

58
        const connection = this.driver.connection
220,947✔
59
        const options = connection.options as SqliteConnectionOptions
220,947✔
60
        const maxQueryExecutionTime = this.driver.options.maxQueryExecutionTime
220,947✔
61
        const broadcaster = this.broadcaster
220,947✔
62

63
        if (!connection.isInitialized) {
220,947✔
64
            throw new ConnectionIsNotSetError("sqlite")
3✔
65
        }
66

67
        const databaseConnection = await this.connect()
220,944✔
68

69
        this.driver.connection.logger.logQuery(query, parameters, this)
220,944✔
70
        await broadcaster.broadcast("BeforeQuery", query, parameters)
220,944✔
71

72
        const broadcasterResult = new BroadcasterResult()
220,944✔
73

74
        return new Promise(async (ok, fail) => {
220,944✔
75
            try {
220,944✔
76
                const queryStartTime = Date.now()
220,944✔
77
                const isInsertQuery = query.startsWith("INSERT ")
220,944✔
78
                const isDeleteQuery = query.startsWith("DELETE ")
220,944✔
79
                const isUpdateQuery = query.startsWith("UPDATE ")
220,944✔
80

81
                const execute = async () => {
220,944✔
82
                    if (isInsertQuery || isDeleteQuery || isUpdateQuery) {
220,944✔
83
                        await databaseConnection.run(query, parameters, handler)
36,141✔
84
                    } else {
85
                        await databaseConnection.all(query, parameters, handler)
184,803✔
86
                    }
87
                }
88

89
                const self = this
220,944✔
90
                const handler = function (this: any, err: any, rows: any) {
220,944✔
91
                    if (err && err.toString().indexOf("SQLITE_BUSY:") !== -1) {
220,944!
UNCOV
92
                        if (
×
93
                            typeof options.busyErrorRetry === "number" &&
×
94
                            options.busyErrorRetry > 0
95
                        ) {
UNCOV
96
                            setTimeout(execute, options.busyErrorRetry)
×
97
                            return
×
98
                        }
99
                    }
100

101
                    // log slow queries if maxQueryExecution time is set
102
                    const queryEndTime = Date.now()
220,944✔
103
                    const queryExecutionTime = queryEndTime - queryStartTime
220,944✔
104
                    if (
220,944!
105
                        maxQueryExecutionTime &&
220,944!
106
                        queryExecutionTime > maxQueryExecutionTime
107
                    )
UNCOV
108
                        connection.logger.logQuerySlow(
×
109
                            queryExecutionTime,
110
                            query,
111
                            parameters,
112
                            self,
113
                        )
114

115
                    if (err) {
220,944✔
116
                        connection.logger.logQueryError(
27✔
117
                            err,
118
                            query,
119
                            parameters,
120
                            self,
121
                        )
122
                        broadcaster.broadcastAfterQueryEvent(
27✔
123
                            broadcasterResult,
124
                            query,
125
                            parameters,
126
                            false,
127
                            undefined,
128
                            undefined,
129
                            err,
130
                        )
131

132
                        return fail(
27✔
133
                            new QueryFailedError(query, parameters, err),
134
                        )
135
                    } else {
136
                        const result = new QueryResult()
220,917✔
137

138
                        if (isInsertQuery) {
220,917✔
139
                            result.raw = this["lastID"]
33,777✔
140
                        } else {
141
                            result.raw = rows
187,140✔
142
                        }
143

144
                        broadcaster.broadcastAfterQueryEvent(
220,917✔
145
                            broadcasterResult,
146
                            query,
147
                            parameters,
148
                            true,
149
                            queryExecutionTime,
150
                            result.raw,
151
                            undefined,
152
                        )
153

154
                        if (Array.isArray(rows)) {
220,917✔
155
                            result.records = rows
184,794✔
156
                        }
157

158
                        result.affected = this["changes"]
220,917✔
159

160
                        if (useStructuredResult) {
220,917✔
161
                            ok(result)
51,708✔
162
                        } else {
163
                            ok(result.raw)
169,209✔
164
                        }
165
                    }
166
                }
167

168
                await execute()
220,944✔
169
            } catch (err) {
UNCOV
170
                fail(err)
×
171
            } finally {
172
                await broadcasterResult.wait()
220,944✔
173
            }
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