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

typeorm / typeorm / 12968994847

25 Jan 2025 10:33PM UTC coverage: 71.671% (-0.7%) from 72.369%
12968994847

Pull #11262

github

web-flow
Merge f05a3d4e8 into 79960e136
Pull Request #11262: ci(PR): adjust timeouts and add concurrency

8567 of 12650 branches covered (67.72%)

Branch coverage included in aggregate %.

17727 of 24037 relevant lines covered (73.75%)

135711.91 hits per line

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

9.2
/src/driver/sqlite/SqliteQueryRunner.ts
1
import { QueryRunnerAlreadyReleasedError } from "../../error/QueryRunnerAlreadyReleasedError"
29✔
2
import { QueryFailedError } from "../../error/QueryFailedError"
29✔
3
import { AbstractSqliteQueryRunner } from "../sqlite-abstract/AbstractSqliteQueryRunner"
29✔
4
import { SqliteConnectionOptions } from "./SqliteConnectionOptions"
5
import { SqliteDriver } from "./SqliteDriver"
6
import { Broadcaster } from "../../subscriber/Broadcaster"
29✔
7
import { ConnectionIsNotSetError } from "../../error/ConnectionIsNotSetError"
29✔
8
import { QueryResult } from "../../query-runner/QueryResult"
29✔
9
import { BroadcasterResult } from "../../subscriber/BroadcasterResult"
29✔
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 {
29✔
18
    /**
19
     * Database driver used by connection.
20
     */
21
    driver: SqliteDriver
22

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

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

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

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

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

58
        const connection = this.driver.connection
×
59
        const options = connection.options as SqliteConnectionOptions
×
60
        const maxQueryExecutionTime = this.driver.options.maxQueryExecutionTime
×
61
        const broadcasterResult = new BroadcasterResult()
×
62
        const broadcaster = this.broadcaster
×
63

64
        broadcaster.broadcastBeforeQueryEvent(
×
65
            broadcasterResult,
66
            query,
67
            parameters,
68
        )
69

70
        if (!connection.isInitialized) {
×
71
            throw new ConnectionIsNotSetError("sqlite")
×
72
        }
73

74
        return new Promise(async (ok, fail) => {
×
75
            try {
×
76
                const databaseConnection = await this.connect()
×
77
                this.driver.connection.logger.logQuery(query, parameters, this)
×
78
                const queryStartTime = +new Date()
×
79
                const isInsertQuery = query.startsWith("INSERT ")
×
80
                const isDeleteQuery = query.startsWith("DELETE ")
×
81
                const isUpdateQuery = query.startsWith("UPDATE ")
×
82

83
                const execute = async () => {
×
84
                    if (isInsertQuery || isDeleteQuery || isUpdateQuery) {
×
85
                        await databaseConnection.run(query, parameters, handler)
×
86
                    } else {
87
                        await databaseConnection.all(query, parameters, handler)
×
88
                    }
89
                }
90

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

103
                    // log slow queries if maxQueryExecution time is set
104
                    const queryEndTime = +new Date()
×
105
                    const queryExecutionTime = queryEndTime - queryStartTime
×
106
                    if (
×
107
                        maxQueryExecutionTime &&
×
108
                        queryExecutionTime > maxQueryExecutionTime
109
                    )
110
                        connection.logger.logQuerySlow(
×
111
                            queryExecutionTime,
112
                            query,
113
                            parameters,
114
                            self,
115
                        )
116

117
                    if (err) {
×
118
                        connection.logger.logQueryError(
×
119
                            err,
120
                            query,
121
                            parameters,
122
                            self,
123
                        )
124
                        broadcaster.broadcastAfterQueryEvent(
×
125
                            broadcasterResult,
126
                            query,
127
                            parameters,
128
                            false,
129
                            undefined,
130
                            undefined,
131
                            err,
132
                        )
133

134
                        return fail(
×
135
                            new QueryFailedError(query, parameters, err),
136
                        )
137
                    } else {
138
                        const result = new QueryResult()
×
139

140
                        if (isInsertQuery) {
×
141
                            result.raw = this["lastID"]
×
142
                        } else {
143
                            result.raw = rows
×
144
                        }
145

146
                        broadcaster.broadcastAfterQueryEvent(
×
147
                            broadcasterResult,
148
                            query,
149
                            parameters,
150
                            true,
151
                            queryExecutionTime,
152
                            result.raw,
153
                            undefined,
154
                        )
155

156
                        if (Array.isArray(rows)) {
×
157
                            result.records = rows
×
158
                        }
159

160
                        result.affected = this["changes"]
×
161

162
                        if (useStructuredResult) {
×
163
                            ok(result)
×
164
                        } else {
165
                            ok(result.raw)
×
166
                        }
167
                    }
168
                }
169

170
                await execute()
×
171
            } catch (err) {
172
                fail(err)
×
173
            } finally {
174
                await broadcasterResult.wait()
×
175
            }
176
        })
177
    }
178
}
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