• 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

91.43
/src/driver/better-sqlite3/BetterSqlite3QueryRunner.ts
1
import { QueryRunnerAlreadyReleasedError } from "../../error/QueryRunnerAlreadyReleasedError"
26✔
2
import { QueryFailedError } from "../../error/QueryFailedError"
26✔
3
import { AbstractSqliteQueryRunner } from "../sqlite-abstract/AbstractSqliteQueryRunner"
26✔
4
import { Broadcaster } from "../../subscriber/Broadcaster"
26✔
5
import { BetterSqlite3Driver } from "./BetterSqlite3Driver"
26✔
6
import { QueryResult } from "../../query-runner/QueryResult"
26✔
7
import { BroadcasterResult } from "../../subscriber/BroadcasterResult"
26✔
8

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

26✔
21
    // -------------------------------------------------------------------------
26✔
22
    // Constructor
26✔
23
    // -------------------------------------------------------------------------
26✔
24

26✔
25
    constructor(driver: BetterSqlite3Driver) {
26✔
26
        super()
1,407✔
27
        this.driver = driver
1,407✔
28
        this.connection = driver.connection
1,407✔
29
        this.broadcaster = new Broadcaster(this)
1,407✔
30
        if (typeof this.driver.options.statementCacheSize === "number") {
1,407!
31
            this.cacheSize = this.driver.options.statementCacheSize
×
32
        } else {
1,407✔
33
            this.cacheSize = 100
1,407✔
34
        }
1,407✔
35
    }
1,407✔
36

26✔
37
    private cacheSize: number
26✔
38
    private stmtCache = new Map<string, any>()
26✔
39

26✔
40
    private async getStmt(query: string) {
26✔
41
        if (this.cacheSize > 0) {
215,268✔
42
            let stmt = this.stmtCache.get(query)
215,268✔
43
            if (!stmt) {
215,268✔
44
                const databaseConnection = await this.connect()
61,299✔
45
                stmt = databaseConnection.prepare(query)
61,299✔
46
                this.stmtCache.set(query, stmt)
61,299✔
47
                while (this.stmtCache.size > this.cacheSize) {
61,299✔
48
                    // since es6 map keeps the insertion order,
17,871✔
49
                    // it comes to be FIFO cache
17,871✔
50
                    const key = this.stmtCache.keys().next().value!
17,871✔
51
                    this.stmtCache.delete(key)
17,871✔
52
                }
17,871✔
53
            }
61,299✔
54
            return stmt
215,259✔
55
        } else {
215,268!
56
            const databaseConnection = await this.connect()
×
57
            return databaseConnection.prepare(query)
×
58
        }
×
59
    }
215,268✔
60

26✔
61
    /**
26✔
62
     * Called before migrations are run.
26✔
63
     */
26✔
64
    async beforeMigration(): Promise<void> {
26✔
65
        await this.query(`PRAGMA foreign_keys = OFF`)
4,083✔
66
    }
4,083✔
67

26✔
68
    /**
26✔
69
     * Called after migrations are run.
26✔
70
     */
26✔
71
    async afterMigration(): Promise<void> {
26✔
72
        await this.query(`PRAGMA foreign_keys = ON`)
4,074✔
73
    }
4,074✔
74

26✔
75
    /**
26✔
76
     * Executes a given SQL query.
26✔
77
     */
26✔
78
    async query(
26✔
79
        query: string,
215,268✔
80
        parameters: any[] = [],
215,268✔
81
        useStructuredResult = false,
215,268✔
82
    ): Promise<any> {
215,268✔
83
        if (this.isReleased) throw new QueryRunnerAlreadyReleasedError()
215,268!
84

215,268✔
85
        const connection = this.driver.connection
215,268✔
86

215,268✔
87
        const broadcasterResult = new BroadcasterResult()
215,268✔
88

215,268✔
89
        this.driver.connection.logger.logQuery(query, parameters, this)
215,268✔
90
        this.broadcaster.broadcastBeforeQueryEvent(
215,268✔
91
            broadcasterResult,
215,268✔
92
            query,
215,268✔
93
            parameters,
215,268✔
94
        )
215,268✔
95
        const queryStartTime = Date.now()
215,268✔
96

215,268✔
97
        const stmt = await this.getStmt(query)
215,268✔
98

215,259✔
99
        try {
215,259✔
100
            const result = new QueryResult()
215,259✔
101

215,259✔
102
            if (stmt.reader) {
215,268✔
103
                const raw = stmt.all(...parameters)
48,327✔
104

48,327✔
105
                result.raw = raw
48,327✔
106

48,327✔
107
                if (Array.isArray(raw)) {
48,327✔
108
                    result.records = raw
48,327✔
109
                }
48,327✔
110
            } else {
215,268✔
111
                const raw = stmt.run(...parameters)
166,932✔
112
                result.affected = raw.changes
166,932✔
113
                result.raw = raw.lastInsertRowid
166,932✔
114
            }
166,932✔
115

215,241✔
116
            // log slow queries if maxQueryExecution time is set
215,241✔
117
            const maxQueryExecutionTime =
215,241✔
118
                this.driver.options.maxQueryExecutionTime
215,241✔
119
            const queryEndTime = Date.now()
215,241✔
120
            const queryExecutionTime = queryEndTime - queryStartTime
215,241✔
121
            if (
215,241✔
122
                maxQueryExecutionTime &&
215,241!
123
                queryExecutionTime > maxQueryExecutionTime
×
124
            )
215,268✔
125
                connection.logger.logQuerySlow(
215,268!
126
                    queryExecutionTime,
×
127
                    query,
×
128
                    parameters,
×
129
                    this,
×
130
                )
×
131

215,241✔
132
            this.broadcaster.broadcastAfterQueryEvent(
215,241✔
133
                broadcasterResult,
215,241✔
134
                query,
215,241✔
135
                parameters,
215,241✔
136
                true,
215,241✔
137
                queryExecutionTime,
215,241✔
138
                result.raw,
215,241✔
139
                undefined,
215,241✔
140
            )
215,241✔
141

215,241✔
142
            if (!useStructuredResult) {
215,268✔
143
                return result.raw
163,380✔
144
            }
163,380✔
145

51,861✔
146
            return result
51,861✔
147
        } catch (err) {
215,268✔
148
            connection.logger.logQueryError(err, query, parameters, this)
18✔
149
            throw new QueryFailedError(query, parameters, err)
18✔
150
        }
18✔
151
    }
215,268✔
152

26✔
153
    // -------------------------------------------------------------------------
26✔
154
    // Protected Methods
26✔
155
    // -------------------------------------------------------------------------
26✔
156

26✔
157
    protected async loadTableRecords(
26✔
158
        tablePath: string,
6✔
159
        tableOrIndex: "table" | "index",
6✔
160
    ) {
6✔
161
        const [database, tableName] = this.splitTablePath(tablePath)
6✔
162
        const res = await this.query(
6✔
163
            `SELECT ${
6✔
164
                database ? `'${database}'` : null
6!
165
            } as database, * FROM ${this.escapePath(
6✔
166
                `${database ? `${database}.` : ""}sqlite_master`,
6!
167
            )} WHERE "type" = '${tableOrIndex}' AND "${
6✔
168
                tableOrIndex === "table" ? "name" : "tbl_name"
6✔
169
            }" IN ('${tableName}')`,
6✔
170
        )
6✔
171
        return res
6✔
172
    }
6✔
173
    protected async loadPragmaRecords(tablePath: string, pragma: string) {
26✔
174
        const [database, tableName] = this.splitTablePath(tablePath)
3,780✔
175
        const res = await this.query(
3,780✔
176
            `PRAGMA ${
3,780✔
177
                database ? `"${database}".` : ""
3,780!
178
            }${pragma}("${tableName}")`,
3,780✔
179
        )
3,780✔
180
        return res
3,780✔
181
    }
3,780✔
182
}
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