@sixb/sqlite 0.0.1
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/LICENSE +21 -0
- package/README.md +57 -0
- package/dist/action-run-storage.d.ts +29 -0
- package/dist/action-run-storage.d.ts.map +1 -0
- package/dist/agents/agent-storage.d.ts +25 -0
- package/dist/agents/agent-storage.d.ts.map +1 -0
- package/dist/agents/index.d.ts +6 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/messages.d.ts +14 -0
- package/dist/agents/messages.d.ts.map +1 -0
- package/dist/agents/rows.d.ts +77 -0
- package/dist/agents/rows.d.ts.map +1 -0
- package/dist/agents/runs.d.ts +26 -0
- package/dist/agents/runs.d.ts.map +1 -0
- package/dist/agents/threads.d.ts +14 -0
- package/dist/agents/threads.d.ts.map +1 -0
- package/dist/auth-storage/access-tokens.d.ts +33 -0
- package/dist/auth-storage/access-tokens.d.ts.map +1 -0
- package/dist/auth-storage/auth-storage.d.ts +46 -0
- package/dist/auth-storage/auth-storage.d.ts.map +1 -0
- package/dist/auth-storage/group-memberships.d.ts +21 -0
- package/dist/auth-storage/group-memberships.d.ts.map +1 -0
- package/dist/auth-storage/identities.d.ts +17 -0
- package/dist/auth-storage/identities.d.ts.map +1 -0
- package/dist/auth-storage/index.d.ts +3 -0
- package/dist/auth-storage/index.d.ts.map +1 -0
- package/dist/auth-storage/invitations.d.ts +28 -0
- package/dist/auth-storage/invitations.d.ts.map +1 -0
- package/dist/auth-storage/magic-links.d.ts +28 -0
- package/dist/auth-storage/magic-links.d.ts.map +1 -0
- package/dist/auth-storage/oidc-attempts.d.ts +18 -0
- package/dist/auth-storage/oidc-attempts.d.ts.map +1 -0
- package/dist/auth-storage/rows.d.ts +134 -0
- package/dist/auth-storage/rows.d.ts.map +1 -0
- package/dist/auth-storage/service-account-group-memberships.d.ts +17 -0
- package/dist/auth-storage/service-account-group-memberships.d.ts.map +1 -0
- package/dist/auth-storage/service-accounts.d.ts +14 -0
- package/dist/auth-storage/service-accounts.d.ts.map +1 -0
- package/dist/auth-storage/sessions.d.ts +55 -0
- package/dist/auth-storage/sessions.d.ts.map +1 -0
- package/dist/auth-storage/shared.d.ts +131 -0
- package/dist/auth-storage/shared.d.ts.map +1 -0
- package/dist/auth-storage/users.d.ts +19 -0
- package/dist/auth-storage/users.d.ts.map +1 -0
- package/dist/index.d.ts +71 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10204 -0
- package/dist/index.js.map +54 -0
- package/dist/latest-run-query.d.ts +22 -0
- package/dist/latest-run-query.d.ts.map +1 -0
- package/dist/migrations.d.ts +18 -0
- package/dist/migrations.d.ts.map +1 -0
- package/dist/object-query-compiler.d.ts +44 -0
- package/dist/object-query-compiler.d.ts.map +1 -0
- package/dist/object-storage.d.ts +93 -0
- package/dist/object-storage.d.ts.map +1 -0
- package/dist/ontology-storage/commits.d.ts +14 -0
- package/dist/ontology-storage/commits.d.ts.map +1 -0
- package/dist/ontology-storage/index.d.ts +22 -0
- package/dist/ontology-storage/index.d.ts.map +1 -0
- package/dist/ontology-storage/materialization-session.d.ts +49 -0
- package/dist/ontology-storage/materialization-session.d.ts.map +1 -0
- package/dist/ontology-storage/materialization-state.d.ts +63 -0
- package/dist/ontology-storage/materialization-state.d.ts.map +1 -0
- package/dist/ontology-storage/materialization-writer.d.ts +15 -0
- package/dist/ontology-storage/materialization-writer.d.ts.map +1 -0
- package/dist/ontology-storage/materializations.d.ts +32 -0
- package/dist/ontology-storage/materializations.d.ts.map +1 -0
- package/dist/ontology-storage/outbox.d.ts +14 -0
- package/dist/ontology-storage/outbox.d.ts.map +1 -0
- package/dist/ontology-storage/shared.d.ts +91 -0
- package/dist/ontology-storage/shared.d.ts.map +1 -0
- package/dist/ontology-storage/sources.d.ts +26 -0
- package/dist/ontology-storage/sources.d.ts.map +1 -0
- package/dist/pipeline-run-storage.d.ts +26 -0
- package/dist/pipeline-run-storage.d.ts.map +1 -0
- package/dist/projection-run-storage.d.ts +32 -0
- package/dist/projection-run-storage.d.ts.map +1 -0
- package/dist/rules-storage.d.ts +33 -0
- package/dist/rules-storage.d.ts.map +1 -0
- package/dist/run-list-query.d.ts +27 -0
- package/dist/run-list-query.d.ts.map +1 -0
- package/dist/storage-errors.d.ts +2 -0
- package/dist/storage-errors.d.ts.map +1 -0
- package/dist/sync-run-storage.d.ts +23 -0
- package/dist/sync-run-storage.d.ts.map +1 -0
- package/dist/timeseries-storage.d.ts +41 -0
- package/dist/timeseries-storage.d.ts.map +1 -0
- package/dist/transactions.d.ts +15 -0
- package/dist/transactions.d.ts.map +1 -0
- package/dist/tsconfig.json +5 -0
- package/dist/validation.d.ts +5 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/webhook-delivery-storage.d.ts +27 -0
- package/dist/webhook-delivery-storage.d.ts.map +1 -0
- package/dist/webhook-run-storage.d.ts +22 -0
- package/dist/webhook-run-storage.d.ts.map +1 -0
- package/dist/workflow-intervention-storage.d.ts +26 -0
- package/dist/workflow-intervention-storage.d.ts.map +1 -0
- package/dist/workflow-run-storage.d.ts +63 -0
- package/dist/workflow-run-storage.d.ts.map +1 -0
- package/package.json +58 -0
- package/src/action-run-storage.ts +761 -0
- package/src/agents/agent-storage.ts +46 -0
- package/src/agents/index.ts +5 -0
- package/src/agents/messages.ts +162 -0
- package/src/agents/rows.ts +205 -0
- package/src/agents/runs.ts +389 -0
- package/src/agents/threads.ts +133 -0
- package/src/auth-storage/access-tokens.ts +289 -0
- package/src/auth-storage/auth-storage.ts +784 -0
- package/src/auth-storage/group-memberships.ts +52 -0
- package/src/auth-storage/identities.ts +98 -0
- package/src/auth-storage/index.ts +2 -0
- package/src/auth-storage/invitations.ts +258 -0
- package/src/auth-storage/magic-links.ts +149 -0
- package/src/auth-storage/oidc-attempts.ts +109 -0
- package/src/auth-storage/rows.ts +338 -0
- package/src/auth-storage/service-account-group-memberships.ts +161 -0
- package/src/auth-storage/service-accounts.ts +168 -0
- package/src/auth-storage/sessions.ts +230 -0
- package/src/auth-storage/shared.ts +707 -0
- package/src/auth-storage/users.ts +226 -0
- package/src/index.ts +292 -0
- package/src/latest-run-query.ts +49 -0
- package/src/migrations/001-initial-schema.sql +1068 -0
- package/src/migrations.ts +245 -0
- package/src/object-query-compiler.ts +1198 -0
- package/src/object-storage.ts +605 -0
- package/src/ontology-storage/commits.ts +127 -0
- package/src/ontology-storage/index.ts +35 -0
- package/src/ontology-storage/materialization-session.ts +393 -0
- package/src/ontology-storage/materialization-state.ts +901 -0
- package/src/ontology-storage/materialization-writer.ts +394 -0
- package/src/ontology-storage/materializations.ts +838 -0
- package/src/ontology-storage/outbox.ts +237 -0
- package/src/ontology-storage/shared.ts +269 -0
- package/src/ontology-storage/sources.ts +653 -0
- package/src/pipeline-run-storage.ts +506 -0
- package/src/projection-run-storage.ts +592 -0
- package/src/rules-storage.ts +375 -0
- package/src/run-list-query.ts +98 -0
- package/src/sql.d.ts +4 -0
- package/src/storage-errors.ts +3 -0
- package/src/sync-run-storage.ts +299 -0
- package/src/timeseries-storage.ts +212 -0
- package/src/transactions.ts +96 -0
- package/src/validation.ts +30 -0
- package/src/webhook-delivery-storage.ts +272 -0
- package/src/webhook-run-storage.ts +240 -0
- package/src/workflow-intervention-storage.ts +398 -0
- package/src/workflow-run-storage.ts +1148 -0
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
import type { Database } from "bun:sqlite"
|
|
2
|
+
import {
|
|
3
|
+
linkRefKey,
|
|
4
|
+
MaterializationConflictError,
|
|
5
|
+
objectRefKey,
|
|
6
|
+
telemetryPointKey,
|
|
7
|
+
} from "@sixb/core/internal/materialization"
|
|
8
|
+
import {
|
|
9
|
+
effectiveConflict,
|
|
10
|
+
type OverrideEntity,
|
|
11
|
+
overrideEntityColumns as overrideColumns,
|
|
12
|
+
} from "@sixb/core/internal/ontology-storage-provider"
|
|
13
|
+
import type {
|
|
14
|
+
ExactEffectiveLinkWrite,
|
|
15
|
+
ExactEffectiveObjectWrite,
|
|
16
|
+
MaterializationPlanChunk,
|
|
17
|
+
} from "@sixb/core/storage"
|
|
18
|
+
import { assertTimestamp, canonicalJson, isSqliteConstraintError, requireChanges } from "./shared"
|
|
19
|
+
|
|
20
|
+
/** Applies one already-validated exact plan chunk to SQLite authority tables. */
|
|
21
|
+
export class SqliteMaterializationWriter {
|
|
22
|
+
constructor(private readonly db: Database) {}
|
|
23
|
+
|
|
24
|
+
apply(projectId: string, commitId: string, chunk: MaterializationPlanChunk): void {
|
|
25
|
+
this.applyOverrides(projectId, chunk)
|
|
26
|
+
this.applyEffective(projectId, chunk)
|
|
27
|
+
this.applyTimeseries(projectId, chunk)
|
|
28
|
+
this.applyOutbox(projectId, commitId, chunk)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
private applyOverrides(projectId: string, chunk: MaterializationPlanChunk): void {
|
|
32
|
+
const upsert = (
|
|
33
|
+
entity: OverrideEntity,
|
|
34
|
+
item:
|
|
35
|
+
| (typeof chunk.overrides.objectUpserts)[number]
|
|
36
|
+
| (typeof chunk.overrides.linkUpserts)[number]
|
|
37
|
+
): void => {
|
|
38
|
+
const kind = entity.kind
|
|
39
|
+
const key = kind === "object" ? objectRefKey(entity.ref) : linkRefKey(entity.ref)
|
|
40
|
+
const columns = overrideColumns(entity)
|
|
41
|
+
if (item.expectedLastCommitId === null) {
|
|
42
|
+
try {
|
|
43
|
+
this.db
|
|
44
|
+
.query(
|
|
45
|
+
`
|
|
46
|
+
INSERT INTO ontology_overrides (
|
|
47
|
+
project_id, entity_kind, entity_key, entity_sort_key,
|
|
48
|
+
object_type_id, primary_id, source_type_id, source_primary_id,
|
|
49
|
+
link_id, target_type_id, target_primary_id,
|
|
50
|
+
value, last_commit_id, updated_at
|
|
51
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, json(?), ?, ?)
|
|
52
|
+
`
|
|
53
|
+
)
|
|
54
|
+
.run(
|
|
55
|
+
projectId,
|
|
56
|
+
kind,
|
|
57
|
+
key,
|
|
58
|
+
columns.sortKey,
|
|
59
|
+
columns.objectTypeId,
|
|
60
|
+
columns.primaryId,
|
|
61
|
+
columns.sourceTypeId,
|
|
62
|
+
columns.sourcePrimaryId,
|
|
63
|
+
columns.linkId,
|
|
64
|
+
columns.targetTypeId,
|
|
65
|
+
columns.targetPrimaryId,
|
|
66
|
+
canonicalJson(item.value),
|
|
67
|
+
item.lastCommitId,
|
|
68
|
+
item.updatedAt
|
|
69
|
+
)
|
|
70
|
+
} catch (error) {
|
|
71
|
+
if (isSqliteConstraintError(error)) {
|
|
72
|
+
throw effectiveConflict(`Expected ${kind} override changed.`)
|
|
73
|
+
}
|
|
74
|
+
throw error
|
|
75
|
+
}
|
|
76
|
+
} else {
|
|
77
|
+
requireChanges(
|
|
78
|
+
this.db
|
|
79
|
+
.query(
|
|
80
|
+
`
|
|
81
|
+
UPDATE ontology_overrides
|
|
82
|
+
SET value = json(?), last_commit_id = ?, updated_at = ?
|
|
83
|
+
WHERE project_id = ? AND entity_kind = ? AND entity_key = ?
|
|
84
|
+
AND last_commit_id = ?
|
|
85
|
+
`
|
|
86
|
+
)
|
|
87
|
+
.run(
|
|
88
|
+
canonicalJson(item.value),
|
|
89
|
+
item.lastCommitId,
|
|
90
|
+
item.updatedAt,
|
|
91
|
+
projectId,
|
|
92
|
+
kind,
|
|
93
|
+
key,
|
|
94
|
+
item.expectedLastCommitId
|
|
95
|
+
).changes,
|
|
96
|
+
"effective-state",
|
|
97
|
+
`Expected ${kind} override changed.`
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
for (const item of chunk.overrides.objectUpserts) {
|
|
102
|
+
upsert({ kind: "object", ref: item.ref }, item)
|
|
103
|
+
}
|
|
104
|
+
for (const item of chunk.overrides.objectDeletes) {
|
|
105
|
+
requireChanges(
|
|
106
|
+
this.db
|
|
107
|
+
.query(
|
|
108
|
+
`DELETE FROM ontology_overrides
|
|
109
|
+
WHERE project_id = ? AND entity_kind = 'object' AND entity_key = ? AND last_commit_id = ?`
|
|
110
|
+
)
|
|
111
|
+
.run(projectId, objectRefKey(item.ref), item.expectedLastCommitId).changes,
|
|
112
|
+
"effective-state",
|
|
113
|
+
"Expected object override changed."
|
|
114
|
+
)
|
|
115
|
+
}
|
|
116
|
+
for (const item of chunk.overrides.linkUpserts) {
|
|
117
|
+
upsert({ kind: "link", ref: item.ref }, item)
|
|
118
|
+
}
|
|
119
|
+
for (const item of chunk.overrides.linkDeletes) {
|
|
120
|
+
requireChanges(
|
|
121
|
+
this.db
|
|
122
|
+
.query(
|
|
123
|
+
`DELETE FROM ontology_overrides
|
|
124
|
+
WHERE project_id = ? AND entity_kind = 'link' AND entity_key = ? AND last_commit_id = ?`
|
|
125
|
+
)
|
|
126
|
+
.run(projectId, linkRefKey(item.ref), item.expectedLastCommitId).changes,
|
|
127
|
+
"effective-state",
|
|
128
|
+
"Expected link override changed."
|
|
129
|
+
)
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
private applyEffective(projectId: string, chunk: MaterializationPlanChunk): void {
|
|
134
|
+
for (const item of chunk.effective.linkDeletes) {
|
|
135
|
+
requireChanges(
|
|
136
|
+
this.db
|
|
137
|
+
.query(
|
|
138
|
+
`
|
|
139
|
+
DELETE FROM links
|
|
140
|
+
WHERE project_id = ? AND source_type_id = ? AND source_id = ? AND link_id = ?
|
|
141
|
+
AND target_type_id = ? AND target_id = ? AND last_commit_id = ?
|
|
142
|
+
`
|
|
143
|
+
)
|
|
144
|
+
.run(
|
|
145
|
+
projectId,
|
|
146
|
+
item.ref.source.objectTypeId,
|
|
147
|
+
item.ref.source.primaryId,
|
|
148
|
+
item.ref.linkId,
|
|
149
|
+
item.ref.target.objectTypeId,
|
|
150
|
+
item.ref.target.primaryId,
|
|
151
|
+
item.expected.lastCommitId
|
|
152
|
+
).changes,
|
|
153
|
+
"effective-state",
|
|
154
|
+
`Expected link ${linkRefKey(item.ref)} changed.`
|
|
155
|
+
)
|
|
156
|
+
}
|
|
157
|
+
for (const item of chunk.effective.objectDeletes) {
|
|
158
|
+
requireChanges(
|
|
159
|
+
this.db
|
|
160
|
+
.query(
|
|
161
|
+
`DELETE FROM objects
|
|
162
|
+
WHERE project_id = ? AND object_type_id = ? AND primary_id = ?
|
|
163
|
+
AND version = ? AND last_commit_id = ?`
|
|
164
|
+
)
|
|
165
|
+
.run(
|
|
166
|
+
projectId,
|
|
167
|
+
item.ref.objectTypeId,
|
|
168
|
+
item.ref.primaryId,
|
|
169
|
+
item.expected.version,
|
|
170
|
+
item.expected.lastCommitId
|
|
171
|
+
).changes,
|
|
172
|
+
"effective-state",
|
|
173
|
+
`Expected object ${objectRefKey(item.ref)} changed.`
|
|
174
|
+
)
|
|
175
|
+
}
|
|
176
|
+
for (const item of chunk.effective.objectUpserts) this.applyObject(projectId, item)
|
|
177
|
+
for (const item of chunk.effective.linkUpserts) this.applyLink(projectId, item)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
private applyObject(projectId: string, item: ExactEffectiveObjectWrite): void {
|
|
181
|
+
const { row, expected } = item
|
|
182
|
+
if (!expected.exists) {
|
|
183
|
+
try {
|
|
184
|
+
this.db
|
|
185
|
+
.query(
|
|
186
|
+
`
|
|
187
|
+
INSERT INTO objects (
|
|
188
|
+
project_id, object_type_id, primary_id, properties, created_at,
|
|
189
|
+
updated_at, version, last_commit_id
|
|
190
|
+
) VALUES (?, ?, ?, json(?), ?, ?, ?, ?)
|
|
191
|
+
`
|
|
192
|
+
)
|
|
193
|
+
.run(
|
|
194
|
+
projectId,
|
|
195
|
+
row.ref.objectTypeId,
|
|
196
|
+
row.ref.primaryId,
|
|
197
|
+
canonicalJson(row.properties),
|
|
198
|
+
row.createdAt,
|
|
199
|
+
row.updatedAt,
|
|
200
|
+
row.version,
|
|
201
|
+
row.lastCommitId
|
|
202
|
+
)
|
|
203
|
+
} catch (error) {
|
|
204
|
+
if (isSqliteConstraintError(error)) {
|
|
205
|
+
throw effectiveConflict(`Expected object ${objectRefKey(row.ref)} to be absent.`)
|
|
206
|
+
}
|
|
207
|
+
throw error
|
|
208
|
+
}
|
|
209
|
+
return
|
|
210
|
+
}
|
|
211
|
+
requireChanges(
|
|
212
|
+
this.db
|
|
213
|
+
.query(
|
|
214
|
+
`
|
|
215
|
+
UPDATE objects
|
|
216
|
+
SET properties = json(?), created_at = ?, updated_at = ?, version = ?,
|
|
217
|
+
last_commit_id = ?
|
|
218
|
+
WHERE project_id = ? AND object_type_id = ? AND primary_id = ?
|
|
219
|
+
AND version = ? AND last_commit_id = ?
|
|
220
|
+
`
|
|
221
|
+
)
|
|
222
|
+
.run(
|
|
223
|
+
canonicalJson(row.properties),
|
|
224
|
+
row.createdAt,
|
|
225
|
+
row.updatedAt,
|
|
226
|
+
row.version,
|
|
227
|
+
row.lastCommitId,
|
|
228
|
+
projectId,
|
|
229
|
+
row.ref.objectTypeId,
|
|
230
|
+
row.ref.primaryId,
|
|
231
|
+
expected.version,
|
|
232
|
+
expected.lastCommitId
|
|
233
|
+
).changes,
|
|
234
|
+
"effective-state",
|
|
235
|
+
`Expected object ${objectRefKey(row.ref)} changed.`
|
|
236
|
+
)
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
private applyLink(projectId: string, item: ExactEffectiveLinkWrite): void {
|
|
240
|
+
const { row, expected } = item
|
|
241
|
+
if (!expected.exists) {
|
|
242
|
+
try {
|
|
243
|
+
this.db
|
|
244
|
+
.query(
|
|
245
|
+
`
|
|
246
|
+
INSERT INTO links (
|
|
247
|
+
project_id, source_type_id, source_id, link_id, target_type_id, target_id,
|
|
248
|
+
properties, created_at, updated_at, last_commit_id
|
|
249
|
+
) VALUES (?, ?, ?, ?, ?, ?, json(?), ?, ?, ?)
|
|
250
|
+
`
|
|
251
|
+
)
|
|
252
|
+
.run(
|
|
253
|
+
projectId,
|
|
254
|
+
row.ref.source.objectTypeId,
|
|
255
|
+
row.ref.source.primaryId,
|
|
256
|
+
row.ref.linkId,
|
|
257
|
+
row.ref.target.objectTypeId,
|
|
258
|
+
row.ref.target.primaryId,
|
|
259
|
+
row.properties === undefined ? null : canonicalJson(row.properties),
|
|
260
|
+
row.createdAt,
|
|
261
|
+
row.updatedAt,
|
|
262
|
+
row.lastCommitId
|
|
263
|
+
)
|
|
264
|
+
} catch (error) {
|
|
265
|
+
if (isSqliteConstraintError(error)) {
|
|
266
|
+
throw effectiveConflict(`Expected link ${linkRefKey(row.ref)} to be absent.`)
|
|
267
|
+
}
|
|
268
|
+
throw error
|
|
269
|
+
}
|
|
270
|
+
return
|
|
271
|
+
}
|
|
272
|
+
requireChanges(
|
|
273
|
+
this.db
|
|
274
|
+
.query(
|
|
275
|
+
`
|
|
276
|
+
UPDATE links
|
|
277
|
+
SET properties = json(?), created_at = ?, updated_at = ?,
|
|
278
|
+
last_commit_id = ?
|
|
279
|
+
WHERE project_id = ? AND source_type_id = ? AND source_id = ? AND link_id = ?
|
|
280
|
+
AND target_type_id = ? AND target_id = ? AND last_commit_id = ?
|
|
281
|
+
`
|
|
282
|
+
)
|
|
283
|
+
.run(
|
|
284
|
+
row.properties === undefined ? null : canonicalJson(row.properties),
|
|
285
|
+
row.createdAt,
|
|
286
|
+
row.updatedAt,
|
|
287
|
+
row.lastCommitId,
|
|
288
|
+
projectId,
|
|
289
|
+
row.ref.source.objectTypeId,
|
|
290
|
+
row.ref.source.primaryId,
|
|
291
|
+
row.ref.linkId,
|
|
292
|
+
row.ref.target.objectTypeId,
|
|
293
|
+
row.ref.target.primaryId,
|
|
294
|
+
expected.lastCommitId
|
|
295
|
+
).changes,
|
|
296
|
+
"effective-state",
|
|
297
|
+
`Expected link ${linkRefKey(row.ref)} changed.`
|
|
298
|
+
)
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
private applyTimeseries(projectId: string, chunk: MaterializationPlanChunk): void {
|
|
302
|
+
for (const item of chunk.timeseries.pointUpserts) {
|
|
303
|
+
const { point, expected } = item
|
|
304
|
+
if (expected.lastCommitId === null) {
|
|
305
|
+
try {
|
|
306
|
+
this.db
|
|
307
|
+
.query(
|
|
308
|
+
`
|
|
309
|
+
INSERT INTO timeseries (
|
|
310
|
+
project_id, object_type_id, object_id, property_id,
|
|
311
|
+
value, unit, at, last_commit_id
|
|
312
|
+
) VALUES (?, ?, ?, ?, json(?), ?, ?, ?)
|
|
313
|
+
`
|
|
314
|
+
)
|
|
315
|
+
.run(
|
|
316
|
+
projectId,
|
|
317
|
+
point.series.object.objectTypeId,
|
|
318
|
+
point.series.object.primaryId,
|
|
319
|
+
point.series.propertyId,
|
|
320
|
+
canonicalJson(point.value),
|
|
321
|
+
point.unit ?? null,
|
|
322
|
+
point.at,
|
|
323
|
+
point.lastCommitId
|
|
324
|
+
)
|
|
325
|
+
} catch (error) {
|
|
326
|
+
if (isSqliteConstraintError(error)) {
|
|
327
|
+
throw new MaterializationConflictError(
|
|
328
|
+
"timeseries-point",
|
|
329
|
+
`Telemetry point ${telemetryPointKey(point.series, point.at)} changed.`
|
|
330
|
+
)
|
|
331
|
+
}
|
|
332
|
+
throw error
|
|
333
|
+
}
|
|
334
|
+
} else {
|
|
335
|
+
requireChanges(
|
|
336
|
+
this.db
|
|
337
|
+
.query(
|
|
338
|
+
`
|
|
339
|
+
UPDATE timeseries
|
|
340
|
+
SET value = json(?), unit = ?, last_commit_id = ?
|
|
341
|
+
WHERE project_id = ? AND object_type_id = ? AND object_id = ?
|
|
342
|
+
AND property_id = ? AND at = ? AND last_commit_id = ?
|
|
343
|
+
`
|
|
344
|
+
)
|
|
345
|
+
.run(
|
|
346
|
+
canonicalJson(point.value),
|
|
347
|
+
point.unit ?? null,
|
|
348
|
+
point.lastCommitId,
|
|
349
|
+
projectId,
|
|
350
|
+
point.series.object.objectTypeId,
|
|
351
|
+
point.series.object.primaryId,
|
|
352
|
+
point.series.propertyId,
|
|
353
|
+
point.at,
|
|
354
|
+
expected.lastCommitId
|
|
355
|
+
).changes,
|
|
356
|
+
"timeseries-point",
|
|
357
|
+
`Telemetry point ${telemetryPointKey(point.series, point.at)} changed.`
|
|
358
|
+
)
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
private applyOutbox(projectId: string, commitId: string, chunk: MaterializationPlanChunk): void {
|
|
364
|
+
const insert = this.db.query(
|
|
365
|
+
`
|
|
366
|
+
INSERT INTO ontology_outbox (
|
|
367
|
+
project_id, id, commit_id, commit_ordinal, envelope,
|
|
368
|
+
available_at, attempts, lease_id, lease_expires_at,
|
|
369
|
+
published_at, last_error, created_at
|
|
370
|
+
) VALUES (?, ?, ?, ?, json(?), ?, 0, NULL, NULL, NULL, NULL, ?)
|
|
371
|
+
`
|
|
372
|
+
)
|
|
373
|
+
for (const item of chunk.outbox) {
|
|
374
|
+
assertTimestamp(item.availableAt, "Outbox availableAt")
|
|
375
|
+
assertTimestamp(item.createdAt, "Outbox createdAt")
|
|
376
|
+
try {
|
|
377
|
+
insert.run(
|
|
378
|
+
projectId,
|
|
379
|
+
item.envelope.id,
|
|
380
|
+
commitId,
|
|
381
|
+
item.envelope.commitOrdinal,
|
|
382
|
+
canonicalJson(item.envelope),
|
|
383
|
+
item.availableAt,
|
|
384
|
+
item.createdAt
|
|
385
|
+
)
|
|
386
|
+
} catch (error) {
|
|
387
|
+
if (isSqliteConstraintError(error)) {
|
|
388
|
+
throw effectiveConflict(`Duplicate outbox event '${item.envelope.id}'.`)
|
|
389
|
+
}
|
|
390
|
+
throw error
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|