@sixb/sqlite 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -13
- package/dist/action-run-storage.d.ts +5 -2
- package/dist/action-run-storage.d.ts.map +1 -1
- package/dist/agents/agent-storage.d.ts +4 -2
- package/dist/agents/agent-storage.d.ts.map +1 -1
- package/dist/agents/rows.d.ts +3 -10
- package/dist/agents/rows.d.ts.map +1 -1
- package/dist/agents/runs.d.ts +3 -2
- package/dist/agents/runs.d.ts.map +1 -1
- package/dist/ai-usage-storage.d.ts +22 -0
- package/dist/ai-usage-storage.d.ts.map +1 -0
- package/dist/auth-storage/service-accounts.d.ts.map +1 -1
- package/dist/auth-storage/shared.d.ts +1 -10
- package/dist/auth-storage/shared.d.ts.map +1 -1
- package/dist/connector-connection-storage.d.ts +9 -0
- package/dist/connector-connection-storage.d.ts.map +1 -0
- package/dist/execution-storage.d.ts +14 -0
- package/dist/execution-storage.d.ts.map +1 -0
- package/dist/index.d.ts +13 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4114 -1149
- package/dist/index.js.map +30 -27
- package/dist/latest-run-query.d.ts.map +1 -1
- package/dist/migrations.d.ts +0 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/ontology-storage/materialization-session.d.ts +50 -8
- package/dist/ontology-storage/materialization-session.d.ts.map +1 -1
- package/dist/ontology-storage/materialization-state.d.ts +4 -5
- package/dist/ontology-storage/materialization-state.d.ts.map +1 -1
- package/dist/ontology-storage/materialization-writer.d.ts.map +1 -1
- package/dist/ontology-storage/materializations.d.ts +0 -2
- package/dist/ontology-storage/materializations.d.ts.map +1 -1
- package/dist/ontology-storage/outbox.d.ts.map +1 -1
- package/dist/ontology-storage/shared.d.ts +3 -3
- package/dist/ontology-storage/shared.d.ts.map +1 -1
- package/dist/ontology-storage/sources.d.ts.map +1 -1
- package/dist/pipeline-run-storage.d.ts +7 -2
- package/dist/pipeline-run-storage.d.ts.map +1 -1
- package/dist/projection-run-storage.d.ts +9 -2
- package/dist/projection-run-storage.d.ts.map +1 -1
- package/dist/run-list-query.d.ts +1 -1
- package/dist/run-list-query.d.ts.map +1 -1
- package/dist/sync-run-storage.d.ts +7 -2
- package/dist/sync-run-storage.d.ts.map +1 -1
- package/dist/testing.d.ts +6 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/transactions.d.ts +3 -0
- package/dist/transactions.d.ts.map +1 -1
- package/dist/webhook-run-storage.d.ts +9 -2
- package/dist/webhook-run-storage.d.ts.map +1 -1
- package/dist/workflow-run-storage.d.ts +7 -3
- package/dist/workflow-run-storage.d.ts.map +1 -1
- package/package.json +4 -3
- package/src/action-run-storage.ts +51 -74
- package/src/agents/agent-storage.ts +5 -3
- package/src/agents/rows.ts +8 -40
- package/src/agents/runs.ts +27 -21
- package/src/ai-usage-storage.ts +324 -0
- package/src/auth-storage/service-accounts.ts +14 -21
- package/src/auth-storage/shared.ts +0 -22
- package/src/connector-connection-storage.ts +784 -0
- package/src/execution-storage.ts +158 -0
- package/src/index.ts +63 -22
- package/src/latest-run-query.ts +7 -1
- package/src/migrations/002-workflow-run-output.sql +27 -0
- package/src/migrations/003-merge-sync-runs.sql +71 -0
- package/src/migrations/004-executions.sql +142 -0
- package/src/migrations/005-workflow-executions.sql +7 -0
- package/src/migrations/006-narrow-ontology-source-root-index.sql +4 -0
- package/src/migrations/007-split-overrides.sql +154 -0
- package/src/migrations/008-action-executions.sql +4 -0
- package/src/migrations/009-agent-executions.sql +115 -0
- package/src/migrations/010-ai-usage-accounting-foundation.sql +74 -0
- package/src/migrations/011-sync-failure-record.sql +22 -0
- package/src/migrations/012-pipeline-failure-record.sql +45 -0
- package/src/migrations/013-workflow-failure-record.sql +45 -0
- package/src/migrations/014-agent-failure-record.sql +59 -0
- package/src/migrations/015-projection-failure-record.sql +20 -0
- package/src/migrations/016-webhook-run-failure-record.sql +19 -0
- package/src/migrations/017-action-failure-record.sql +65 -0
- package/src/migrations/018-ontology-outbox-failure-record.sql +80 -0
- package/src/migrations/019-webhook-delivery-failure-record.sql +62 -0
- package/src/migrations/020-drop-run-usage-projections.sql +7 -0
- package/src/migrations/021-sync-pipeline-executions.sql +101 -0
- package/src/migrations/022-projection-executions.sql +244 -0
- package/src/migrations/023-webhook-executions.sql +51 -0
- package/src/migrations/024-ontology-commit-executions.sql +58 -0
- package/src/migrations/025-connector-connections.sql +257 -0
- package/src/migrations.ts +126 -5
- package/src/ontology-storage/materialization-session.ts +317 -143
- package/src/ontology-storage/materialization-state.ts +398 -150
- package/src/ontology-storage/materialization-writer.ts +142 -67
- package/src/ontology-storage/materializations.ts +67 -141
- package/src/ontology-storage/outbox.ts +10 -3
- package/src/ontology-storage/shared.ts +10 -4
- package/src/ontology-storage/sources.ts +4 -1
- package/src/pipeline-run-storage.ts +128 -43
- package/src/projection-run-storage.ts +209 -97
- package/src/run-list-query.ts +9 -4
- package/src/sync-run-storage.ts +120 -34
- package/src/testing.ts +20 -0
- package/src/transactions.ts +10 -3
- package/src/webhook-run-storage.ts +118 -74
- package/src/workflow-run-storage.ts +124 -133
- package/dist/validation.d.ts +0 -5
- package/dist/validation.d.ts.map +0 -1
- package/dist/webhook-delivery-storage.d.ts +0 -27
- package/dist/webhook-delivery-storage.d.ts.map +0 -1
- package/src/validation.ts +0 -30
- package/src/webhook-delivery-storage.ts +0 -272
package/src/sync-run-storage.ts
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
import type { Database } from "bun:sqlite"
|
|
2
2
|
import type { JsonValue } from "@sixb/core"
|
|
3
|
+
import { parseSixbFailure, serializeSixbFailure } from "@sixb/core/internal/errors"
|
|
4
|
+
import { assertSyncRunExecution } from "@sixb/core/internal/sync-run-storage-provider"
|
|
3
5
|
import type {
|
|
6
|
+
ExecutionStorage,
|
|
4
7
|
FinishSyncRunInput,
|
|
5
8
|
ListLatestSyncRunsInput,
|
|
6
9
|
ListLatestSyncRunsResult,
|
|
7
10
|
ListSyncRunsInput,
|
|
8
11
|
ListSyncRunsResult,
|
|
12
|
+
QueueSyncRunInput,
|
|
9
13
|
StartSyncRunInput,
|
|
10
|
-
SyncRunFailure,
|
|
11
14
|
SyncRunRecord,
|
|
12
15
|
SyncRunStorage,
|
|
13
16
|
} from "@sixb/core/storage"
|
|
14
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
canRequeueSyncRunAfterEnqueueFailure,
|
|
19
|
+
SYNC_RUN_FAILURE_CODES,
|
|
20
|
+
SyncRunError,
|
|
21
|
+
} from "@sixb/core/storage"
|
|
15
22
|
import { queryLatestRunsByOwnerId } from "./latest-run-query"
|
|
16
23
|
import { installFreshSqliteSchema } from "./migrations"
|
|
17
24
|
import {
|
|
@@ -27,6 +34,8 @@ import {
|
|
|
27
34
|
} from "./transactions"
|
|
28
35
|
|
|
29
36
|
export interface SqliteSyncRunStorageOptions {
|
|
37
|
+
/** Execution lookup sharing the same provider transaction. */
|
|
38
|
+
executions: ExecutionStorage
|
|
30
39
|
/** Path to SQLite database file. Defaults to ':memory:' for in-memory database. */
|
|
31
40
|
path?: string
|
|
32
41
|
/** Internal shared connection used by bundled SqliteStorage. */
|
|
@@ -36,18 +45,27 @@ export interface SqliteSyncRunStorageOptions {
|
|
|
36
45
|
export class SqliteSyncRunStorage implements SyncRunStorage {
|
|
37
46
|
private readonly connection: SqliteStoreConnection
|
|
38
47
|
private readonly db: Database
|
|
48
|
+
private readonly executions: ExecutionStorage
|
|
39
49
|
|
|
40
|
-
constructor(options: SqliteSyncRunStorageOptions
|
|
50
|
+
constructor(options: SqliteSyncRunStorageOptions) {
|
|
41
51
|
this.connection = openSqliteStoreConnection(options)
|
|
42
52
|
this.db = this.connection.db
|
|
53
|
+
this.executions = options.executions
|
|
43
54
|
|
|
44
55
|
if (this.connection.installFreshSchema) {
|
|
45
56
|
installFreshSqliteSchema(this.db)
|
|
46
57
|
}
|
|
47
58
|
}
|
|
48
59
|
|
|
49
|
-
async
|
|
50
|
-
const
|
|
60
|
+
async queue(input: QueueSyncRunInput): Promise<SyncRunRecord> {
|
|
61
|
+
const queuedAt = input.queuedAt ?? new Date()
|
|
62
|
+
await assertSyncRunExecution({
|
|
63
|
+
executions: this.executions,
|
|
64
|
+
projectId: input.projectId,
|
|
65
|
+
executionId: input.executionId,
|
|
66
|
+
runId: input.id,
|
|
67
|
+
syncId: input.syncId,
|
|
68
|
+
})
|
|
51
69
|
|
|
52
70
|
try {
|
|
53
71
|
this.db
|
|
@@ -56,32 +74,33 @@ export class SqliteSyncRunStorage implements SyncRunStorage {
|
|
|
56
74
|
INSERT INTO sync_runs (
|
|
57
75
|
project_id,
|
|
58
76
|
id,
|
|
77
|
+
execution_id,
|
|
59
78
|
sync_id,
|
|
60
79
|
dataset_id,
|
|
61
80
|
mode,
|
|
62
81
|
status,
|
|
82
|
+
queued_at,
|
|
63
83
|
started_at,
|
|
64
84
|
expected_latest_version_id,
|
|
65
85
|
commit_message
|
|
66
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
86
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?)
|
|
67
87
|
`
|
|
68
88
|
)
|
|
69
89
|
.run(
|
|
70
90
|
input.projectId,
|
|
71
91
|
input.id,
|
|
92
|
+
input.executionId,
|
|
72
93
|
input.syncId,
|
|
73
94
|
input.datasetId,
|
|
74
95
|
input.mode,
|
|
75
|
-
"
|
|
76
|
-
|
|
96
|
+
"queued",
|
|
97
|
+
queuedAt.toISOString(),
|
|
77
98
|
input.expectedLatestVersionId ?? null,
|
|
78
99
|
input.commitMessage ?? null
|
|
79
100
|
)
|
|
80
101
|
} catch (error) {
|
|
81
102
|
if (isUniqueConstraintError(error)) {
|
|
82
|
-
|
|
83
|
-
`[SixbSqlite] Sync run '${input.id}' already exists for project '${input.projectId}'.`
|
|
84
|
-
)
|
|
103
|
+
return this.requeueAfterEnqueueFailure(input, queuedAt)
|
|
85
104
|
}
|
|
86
105
|
|
|
87
106
|
throw error
|
|
@@ -97,6 +116,70 @@ export class SqliteSyncRunStorage implements SyncRunStorage {
|
|
|
97
116
|
return record
|
|
98
117
|
}
|
|
99
118
|
|
|
119
|
+
private async requeueAfterEnqueueFailure(
|
|
120
|
+
input: QueueSyncRunInput,
|
|
121
|
+
queuedAt: Date
|
|
122
|
+
): Promise<SyncRunRecord> {
|
|
123
|
+
return this.db.transaction(() => {
|
|
124
|
+
const existing = this.db
|
|
125
|
+
.query("SELECT * FROM sync_runs WHERE project_id = ? AND id = ?")
|
|
126
|
+
.get(input.projectId, input.id) as DatabaseRow | null
|
|
127
|
+
if (!existing || !canRequeueSyncRunAfterEnqueueFailure(rowToSyncRunRecord(existing), input)) {
|
|
128
|
+
throw new SyncRunError(
|
|
129
|
+
`[SixbSqlite] Sync run '${input.id}' already exists for project '${input.projectId}'.`
|
|
130
|
+
)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
this.db
|
|
134
|
+
.query(
|
|
135
|
+
`
|
|
136
|
+
UPDATE sync_runs
|
|
137
|
+
SET status = ?, queued_at = ?, started_at = NULL, finished_at = NULL,
|
|
138
|
+
rows_read = NULL, output_version_id = NULL, error = NULL, checkpoint = NULL
|
|
139
|
+
WHERE project_id = ? AND id = ?
|
|
140
|
+
`
|
|
141
|
+
)
|
|
142
|
+
.run("queued", queuedAt.toISOString(), input.projectId, input.id)
|
|
143
|
+
|
|
144
|
+
const updated = this.db
|
|
145
|
+
.query("SELECT * FROM sync_runs WHERE project_id = ? AND id = ?")
|
|
146
|
+
.get(input.projectId, input.id) as DatabaseRow
|
|
147
|
+
return rowToSyncRunRecord(updated)
|
|
148
|
+
})()
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async start(input: StartSyncRunInput): Promise<SyncRunRecord> {
|
|
152
|
+
const result = this.db
|
|
153
|
+
.query(
|
|
154
|
+
`
|
|
155
|
+
UPDATE sync_runs
|
|
156
|
+
SET status = ?, started_at = ?, error = NULL
|
|
157
|
+
WHERE project_id = ? AND id = ? AND status = ?
|
|
158
|
+
`
|
|
159
|
+
)
|
|
160
|
+
.run(
|
|
161
|
+
"running",
|
|
162
|
+
(input.startedAt ?? new Date()).toISOString(),
|
|
163
|
+
input.projectId,
|
|
164
|
+
input.id,
|
|
165
|
+
"queued"
|
|
166
|
+
)
|
|
167
|
+
if (result.changes > 0) {
|
|
168
|
+
const record = await this.getById({ projectId: input.projectId, id: input.id })
|
|
169
|
+
if (record) return record
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const existing = await this.getById({ projectId: input.projectId, id: input.id })
|
|
173
|
+
if (!existing) {
|
|
174
|
+
throw new SyncRunError(
|
|
175
|
+
`[SixbSqlite] Sync run '${input.id}' not found for project '${input.projectId}'.`
|
|
176
|
+
)
|
|
177
|
+
}
|
|
178
|
+
throw new SyncRunError(
|
|
179
|
+
`[SixbSqlite] Sync run '${input.id}' cannot start from status '${existing.status}'.`
|
|
180
|
+
)
|
|
181
|
+
}
|
|
182
|
+
|
|
100
183
|
async finish(input: FinishSyncRunInput): Promise<SyncRunRecord> {
|
|
101
184
|
return this.db.transaction(() => {
|
|
102
185
|
const existing = this.db
|
|
@@ -109,15 +192,26 @@ export class SqliteSyncRunStorage implements SyncRunStorage {
|
|
|
109
192
|
)
|
|
110
193
|
}
|
|
111
194
|
|
|
195
|
+
const enqueueFailure =
|
|
196
|
+
input.status === "failed" && input.error.code === "queue.enqueue_failed"
|
|
197
|
+
if (
|
|
198
|
+
(enqueueFailure && existing.status !== "queued") ||
|
|
199
|
+
(!enqueueFailure && existing.status !== "running")
|
|
200
|
+
) {
|
|
201
|
+
throw new SyncRunError(
|
|
202
|
+
`[SixbSqlite] Sync run '${input.id}' cannot finish from status '${existing.status}'.`
|
|
203
|
+
)
|
|
204
|
+
}
|
|
205
|
+
|
|
112
206
|
if (input.status === "succeeded") {
|
|
113
207
|
if (input.output && input.output.datasetId !== existing.dataset_id) {
|
|
114
208
|
throw new SyncRunError(
|
|
115
209
|
`[SixbSqlite] Sync run '${input.id}' output dataset '${input.output.datasetId}' does not match '${existing.dataset_id}'.`
|
|
116
210
|
)
|
|
117
211
|
}
|
|
118
|
-
if (!input.output &&
|
|
212
|
+
if (!input.output && input.rowsRead !== 0 && existing.mode !== "merge") {
|
|
119
213
|
throw new SyncRunError(
|
|
120
|
-
`[SixbSqlite] Sync run '${input.id}' may omit its output only for an
|
|
214
|
+
`[SixbSqlite] Sync run '${input.id}' may omit its output with rows read only for an initial merge no-op.`
|
|
121
215
|
)
|
|
122
216
|
}
|
|
123
217
|
}
|
|
@@ -131,8 +225,7 @@ export class SqliteSyncRunStorage implements SyncRunStorage {
|
|
|
131
225
|
finished_at = ?,
|
|
132
226
|
rows_read = ?,
|
|
133
227
|
output_version_id = ?,
|
|
134
|
-
|
|
135
|
-
error_message = ?,
|
|
228
|
+
error = ?,
|
|
136
229
|
checkpoint = ?
|
|
137
230
|
WHERE project_id = ? AND id = ?
|
|
138
231
|
`
|
|
@@ -144,8 +237,9 @@ export class SqliteSyncRunStorage implements SyncRunStorage {
|
|
|
144
237
|
? input.rowsRead
|
|
145
238
|
: (input.rowsRead ?? existing.rows_read ?? null),
|
|
146
239
|
input.status === "succeeded" ? (input.output?.versionId ?? null) : null,
|
|
147
|
-
input.status === "succeeded"
|
|
148
|
-
|
|
240
|
+
input.status === "succeeded" || input.error === undefined
|
|
241
|
+
? null
|
|
242
|
+
: serializeSixbFailure(input.error, SYNC_RUN_FAILURE_CODES),
|
|
149
243
|
input.status === "succeeded" ? serializeCheckpoint(input.checkpoint) : null,
|
|
150
244
|
input.projectId,
|
|
151
245
|
input.id
|
|
@@ -194,7 +288,7 @@ export class SqliteSyncRunStorage implements SyncRunStorage {
|
|
|
194
288
|
args.push(input.datasetId)
|
|
195
289
|
}
|
|
196
290
|
|
|
197
|
-
appendRunListFilters(whereClauses, args, input)
|
|
291
|
+
appendRunListFilters(whereClauses, args, input, "COALESCE(started_at, queued_at)")
|
|
198
292
|
|
|
199
293
|
const { rows, total, hasMore } = queryRunList<DatabaseRow>({
|
|
200
294
|
db: this.db,
|
|
@@ -241,26 +335,17 @@ function parseCheckpoint(value: string | null | undefined): JsonValue | undefine
|
|
|
241
335
|
return value != null ? (JSON.parse(value) as JsonValue) : undefined
|
|
242
336
|
}
|
|
243
337
|
|
|
244
|
-
function toSyncRunFailure(row: DatabaseRow): SyncRunFailure | undefined {
|
|
245
|
-
if (!row.error_message) {
|
|
246
|
-
return undefined
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
return {
|
|
250
|
-
name: row.error_name ?? undefined,
|
|
251
|
-
message: row.error_message,
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
338
|
function rowToSyncRunRecord(row: DatabaseRow): SyncRunRecord {
|
|
256
339
|
return {
|
|
257
340
|
id: row.id,
|
|
258
341
|
projectId: row.project_id,
|
|
342
|
+
executionId: row.execution_id,
|
|
259
343
|
syncId: row.sync_id,
|
|
260
344
|
datasetId: row.dataset_id,
|
|
261
345
|
mode: row.mode,
|
|
262
346
|
status: row.status,
|
|
263
|
-
|
|
347
|
+
queuedAt: new Date(row.queued_at),
|
|
348
|
+
startedAt: row.started_at ? new Date(row.started_at) : undefined,
|
|
264
349
|
finishedAt: row.finished_at ? new Date(row.finished_at) : undefined,
|
|
265
350
|
rowsRead: row.rows_read ?? undefined,
|
|
266
351
|
output: row.output_version_id
|
|
@@ -271,7 +356,7 @@ function rowToSyncRunRecord(row: DatabaseRow): SyncRunRecord {
|
|
|
271
356
|
: undefined,
|
|
272
357
|
expectedLatestVersionId: row.expected_latest_version_id ?? undefined,
|
|
273
358
|
commitMessage: row.commit_message ?? undefined,
|
|
274
|
-
error:
|
|
359
|
+
error: row.error === null ? undefined : parseSixbFailure(row.error, SYNC_RUN_FAILURE_CODES),
|
|
275
360
|
checkpoint: parseCheckpoint(row.checkpoint),
|
|
276
361
|
}
|
|
277
362
|
}
|
|
@@ -283,17 +368,18 @@ function isUniqueConstraintError(error: unknown): boolean {
|
|
|
283
368
|
interface DatabaseRow {
|
|
284
369
|
project_id: string
|
|
285
370
|
id: string
|
|
371
|
+
execution_id: string
|
|
286
372
|
sync_id: string
|
|
287
373
|
dataset_id: string
|
|
288
374
|
mode: SyncRunRecord["mode"]
|
|
289
375
|
status: SyncRunRecord["status"]
|
|
290
|
-
|
|
376
|
+
queued_at: string
|
|
377
|
+
started_at: string | null
|
|
291
378
|
finished_at: string | null
|
|
292
379
|
rows_read: number | null
|
|
293
380
|
output_version_id: string | null
|
|
294
381
|
expected_latest_version_id: string | null
|
|
295
382
|
commit_message: string | null
|
|
296
|
-
|
|
297
|
-
error_message: string | null
|
|
383
|
+
error: string | null
|
|
298
384
|
checkpoint: string | null
|
|
299
385
|
}
|
package/src/testing.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface SqliteStorageTestingAdapter {
|
|
2
|
+
advanceConnectorConnectionTime(durationMs: number): void
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
const adapters = new WeakMap<object, SqliteStorageTestingAdapter>()
|
|
6
|
+
|
|
7
|
+
export function registerSqliteStorageTestingAdapter(
|
|
8
|
+
storage: object,
|
|
9
|
+
advanceConnectorConnectionTime: (durationMs: number) => void
|
|
10
|
+
): void {
|
|
11
|
+
adapters.set(storage, {
|
|
12
|
+
advanceConnectorConnectionTime,
|
|
13
|
+
})
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function getSqliteStorageTestingAdapter(storage: object): SqliteStorageTestingAdapter {
|
|
17
|
+
const adapter = adapters.get(storage)
|
|
18
|
+
if (!adapter) throw new Error("[SixbSqlite] Storage testing adapter is unavailable.")
|
|
19
|
+
return adapter
|
|
20
|
+
}
|
package/src/transactions.ts
CHANGED
|
@@ -12,6 +12,7 @@ export interface SqliteStoreConnection {
|
|
|
12
12
|
export interface SqliteStoreConnectionOptions {
|
|
13
13
|
readonly path?: string
|
|
14
14
|
readonly connection?: SqliteStoreConnection
|
|
15
|
+
readonly readonly?: boolean
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
export function openSqliteStoreConnection(
|
|
@@ -26,13 +27,14 @@ export function openSqliteStoreConnection(
|
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
const path = options.path ?? ":memory:"
|
|
29
|
-
if (path !== ":memory:") mkdirSync(dirname(path), { recursive: true })
|
|
30
|
-
const db = new SqliteDatabase(path)
|
|
30
|
+
if (path !== ":memory:" && !options.readonly) mkdirSync(dirname(path), { recursive: true })
|
|
31
|
+
const db = new SqliteDatabase(path, options.readonly ? { readonly: true } : undefined)
|
|
31
32
|
db.run("PRAGMA foreign_keys = ON")
|
|
33
|
+
db.run("PRAGMA busy_timeout = 5000")
|
|
32
34
|
return {
|
|
33
35
|
db,
|
|
34
36
|
ownsConnection: true,
|
|
35
|
-
installFreshSchema: path === ":memory:",
|
|
37
|
+
installFreshSchema: path === ":memory:" && !options.readonly,
|
|
36
38
|
}
|
|
37
39
|
}
|
|
38
40
|
|
|
@@ -64,6 +66,11 @@ export function runImmediateTransaction<T>(db: Database, run: () => T): T {
|
|
|
64
66
|
}
|
|
65
67
|
}
|
|
66
68
|
|
|
69
|
+
/** Lets timers and request handlers run between bounded synchronous SQLite chunks. */
|
|
70
|
+
export function yieldSqliteEventLoop(): Promise<void> {
|
|
71
|
+
return new Promise((resolve) => setImmediate(resolve))
|
|
72
|
+
}
|
|
73
|
+
|
|
67
74
|
export async function runImmediateTransactionAsync<T>(
|
|
68
75
|
db: Database,
|
|
69
76
|
run: () => Promise<T> | T
|