@sixb/pg 0.1.1 → 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 +7 -6
- package/dist/agents/agent-storage.d.ts +2 -1
- package/dist/agents/agent-storage.d.ts.map +1 -1
- package/dist/agents/rows.d.ts +4 -11
- 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/auth-storage/service-accounts.d.ts.map +1 -1
- package/dist/auth-storage/shared.d.ts +0 -4
- 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/index.d.ts +8 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3086 -730
- package/dist/index.js.map +28 -25
- package/dist/latest-run-query.d.ts.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/ontology-storage/materialization-session.d.ts.map +1 -1
- package/dist/ontology-storage/materialization-state.d.ts +0 -2
- 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.map +1 -1
- package/dist/ontology-storage/outbox.d.ts.map +1 -1
- package/dist/ontology-storage/shared.d.ts +3 -6
- package/dist/ontology-storage/shared.d.ts.map +1 -1
- package/dist/pg-action-run-storage.d.ts +3 -2
- package/dist/pg-action-run-storage.d.ts.map +1 -1
- package/dist/pg-ai-usage-storage.d.ts +16 -0
- package/dist/pg-ai-usage-storage.d.ts.map +1 -0
- package/dist/pg-execution-storage.d.ts +14 -0
- package/dist/pg-execution-storage.d.ts.map +1 -0
- package/dist/pg-pipeline-run-storage.d.ts +5 -2
- package/dist/pg-pipeline-run-storage.d.ts.map +1 -1
- package/dist/pg-projection-run-storage.d.ts +5 -2
- package/dist/pg-projection-run-storage.d.ts.map +1 -1
- package/dist/pg-sync-run-storage.d.ts +5 -2
- package/dist/pg-sync-run-storage.d.ts.map +1 -1
- package/dist/pg-webhook-run-storage.d.ts +5 -2
- package/dist/pg-webhook-run-storage.d.ts.map +1 -1
- package/dist/pg-workflow-run-storage.d.ts +5 -3
- package/dist/pg-workflow-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/testing.d.ts +6 -0
- package/dist/testing.d.ts.map +1 -0
- package/package.json +3 -3
- package/src/agents/agent-storage.ts +3 -2
- package/src/agents/rows.ts +12 -43
- package/src/agents/runs.ts +29 -15
- package/src/auth-storage/service-accounts.ts +14 -15
- package/src/auth-storage/shared.ts +0 -8
- package/src/connector-connection-storage.ts +760 -0
- package/src/index.ts +32 -15
- package/src/latest-run-query.ts +7 -1
- package/src/migrations/004-executions.sql +140 -0
- package/src/migrations/005-workflow-executions.sql +10 -0
- package/src/migrations/006-narrow-ontology-source-root-index.sql +4 -0
- package/src/migrations/007-split-overrides.sql +153 -0
- package/src/migrations/008-action-executions.sql +7 -0
- package/src/migrations/009-agent-executions.sql +21 -0
- package/src/migrations/010-ai-usage-accounting-foundation.sql +76 -0
- package/src/migrations/011-sync-failure-record.sql +23 -0
- package/src/migrations/012-pipeline-failure-record.sql +47 -0
- package/src/migrations/013-workflow-failure-record.sql +45 -0
- package/src/migrations/014-agent-failure-record.sql +56 -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 +29 -0
- package/src/migrations/019-webhook-delivery-failure-record.sql +27 -0
- package/src/migrations/020-drop-run-usage-projections.sql +8 -0
- package/src/migrations/021-sync-pipeline-executions.sql +50 -0
- package/src/migrations/022-projection-executions.sql +115 -0
- package/src/migrations/023-webhook-executions.sql +30 -0
- package/src/migrations/024-ontology-commit-executions.sql +12 -0
- package/src/migrations/025-connector-connections.sql +231 -0
- package/src/migrations.ts +72 -0
- package/src/ontology-storage/materialization-session.ts +25 -28
- package/src/ontology-storage/materialization-state.ts +159 -43
- package/src/ontology-storage/materialization-writer.ts +146 -75
- package/src/ontology-storage/materializations.ts +3 -1
- package/src/ontology-storage/outbox.ts +9 -2
- package/src/ontology-storage/shared.ts +10 -20
- package/src/pg-action-run-storage.ts +43 -67
- package/src/pg-ai-usage-storage.ts +290 -0
- package/src/pg-execution-storage.ts +147 -0
- package/src/pg-pipeline-run-storage.ts +107 -41
- package/src/pg-projection-run-storage.ts +159 -91
- package/src/pg-sync-run-storage.ts +100 -28
- package/src/pg-webhook-run-storage.ts +89 -57
- package/src/pg-workflow-run-storage.ts +97 -130
- package/src/run-list-query.ts +9 -4
- package/src/testing.ts +18 -0
- package/dist/pg-webhook-delivery-storage.d.ts +0 -17
- package/dist/pg-webhook-delivery-storage.d.ts.map +0 -1
- package/src/pg-webhook-delivery-storage.ts +0 -180
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type ExecutionStorageRow,
|
|
3
|
+
executionRecordFromStorageRow,
|
|
4
|
+
executionRecordToStorageRow,
|
|
5
|
+
normalizeExecutionRecord,
|
|
6
|
+
validateExecutionRecordReferences,
|
|
7
|
+
} from "@sixb/core/internal/execution-storage"
|
|
8
|
+
import type { CreateExecutionInput, ExecutionRecord, ExecutionStorage } from "@sixb/core/storage"
|
|
9
|
+
import { ExecutionStorageError } from "@sixb/core/storage"
|
|
10
|
+
import type { PgAuthStorage } from "./auth-storage"
|
|
11
|
+
import { isUniqueViolation } from "./storage-errors"
|
|
12
|
+
import type { PgStoreClient } from "./transactions"
|
|
13
|
+
|
|
14
|
+
export class PgExecutionStorage implements ExecutionStorage {
|
|
15
|
+
constructor(
|
|
16
|
+
private readonly sql: PgStoreClient,
|
|
17
|
+
private readonly auth: PgAuthStorage
|
|
18
|
+
) {}
|
|
19
|
+
|
|
20
|
+
async create(input: CreateExecutionInput): Promise<ExecutionRecord> {
|
|
21
|
+
const record = normalizeExecutionRecord(input)
|
|
22
|
+
await validateExecutionRecordReferences(record, {
|
|
23
|
+
auth: this.auth,
|
|
24
|
+
getExecution: (params) => this.getById(params),
|
|
25
|
+
})
|
|
26
|
+
const row = executionRecordToStorageRow(record)
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
const [created] = await this.sql<PgExecutionRow[]>`
|
|
30
|
+
INSERT INTO executions (
|
|
31
|
+
project_id,
|
|
32
|
+
id,
|
|
33
|
+
executor_kind,
|
|
34
|
+
executor_id,
|
|
35
|
+
source_kind,
|
|
36
|
+
source_id,
|
|
37
|
+
requested_by_user_id,
|
|
38
|
+
requested_by_service_account_id,
|
|
39
|
+
correlation_id,
|
|
40
|
+
parent_execution_id,
|
|
41
|
+
authority_kind,
|
|
42
|
+
authority_user_id,
|
|
43
|
+
authority_service_account_id,
|
|
44
|
+
authority_session_id,
|
|
45
|
+
authority_access_token_id,
|
|
46
|
+
authority_primitive_kind,
|
|
47
|
+
authority_primitive_id,
|
|
48
|
+
authority_kernel_operation,
|
|
49
|
+
created_at
|
|
50
|
+
) VALUES (
|
|
51
|
+
${row.projectId},
|
|
52
|
+
${row.id},
|
|
53
|
+
${row.executorKind},
|
|
54
|
+
${row.executorId},
|
|
55
|
+
${row.sourceKind},
|
|
56
|
+
${row.sourceId},
|
|
57
|
+
${row.requestedByUserId},
|
|
58
|
+
${row.requestedByServiceAccountId},
|
|
59
|
+
${row.correlationId},
|
|
60
|
+
${row.parentExecutionId},
|
|
61
|
+
${row.authorityKind},
|
|
62
|
+
${row.authorityUserId},
|
|
63
|
+
${row.authorityServiceAccountId},
|
|
64
|
+
${row.authoritySessionId},
|
|
65
|
+
${row.authorityAccessTokenId},
|
|
66
|
+
${row.authorityPrimitiveKind},
|
|
67
|
+
${row.authorityPrimitiveId},
|
|
68
|
+
${row.authorityKernelOperation},
|
|
69
|
+
${row.createdAt}
|
|
70
|
+
)
|
|
71
|
+
RETURNING *
|
|
72
|
+
`
|
|
73
|
+
|
|
74
|
+
if (!created) {
|
|
75
|
+
throw new Error("[SixbPg] Execution insert returned no row.")
|
|
76
|
+
}
|
|
77
|
+
return executionRecordFromStorageRow(toStorageRow(created))
|
|
78
|
+
} catch (error) {
|
|
79
|
+
if (isUniqueViolation(error)) {
|
|
80
|
+
throw new ExecutionStorageError(
|
|
81
|
+
"duplicate_execution",
|
|
82
|
+
`[SixbPg] Execution '${record.id}' already exists in project '${record.projectId}'.`,
|
|
83
|
+
{ cause: error }
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
throw error
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async getById(params: {
|
|
91
|
+
readonly projectId: string
|
|
92
|
+
readonly id: string
|
|
93
|
+
}): Promise<ExecutionRecord | null> {
|
|
94
|
+
const [row] = await this.sql<PgExecutionRow[]>`
|
|
95
|
+
SELECT *
|
|
96
|
+
FROM executions
|
|
97
|
+
WHERE project_id = ${params.projectId} AND id = ${params.id}
|
|
98
|
+
`
|
|
99
|
+
return row ? executionRecordFromStorageRow(toStorageRow(row)) : null
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function toStorageRow(row: PgExecutionRow): ExecutionStorageRow {
|
|
104
|
+
return {
|
|
105
|
+
projectId: row.project_id,
|
|
106
|
+
id: row.id,
|
|
107
|
+
executorKind: row.executor_kind,
|
|
108
|
+
executorId: row.executor_id,
|
|
109
|
+
sourceKind: row.source_kind,
|
|
110
|
+
sourceId: row.source_id,
|
|
111
|
+
requestedByUserId: row.requested_by_user_id,
|
|
112
|
+
requestedByServiceAccountId: row.requested_by_service_account_id,
|
|
113
|
+
correlationId: row.correlation_id,
|
|
114
|
+
parentExecutionId: row.parent_execution_id,
|
|
115
|
+
authorityKind: row.authority_kind,
|
|
116
|
+
authorityUserId: row.authority_user_id,
|
|
117
|
+
authorityServiceAccountId: row.authority_service_account_id,
|
|
118
|
+
authoritySessionId: row.authority_session_id,
|
|
119
|
+
authorityAccessTokenId: row.authority_access_token_id,
|
|
120
|
+
authorityPrimitiveKind: row.authority_primitive_kind,
|
|
121
|
+
authorityPrimitiveId: row.authority_primitive_id,
|
|
122
|
+
authorityKernelOperation: row.authority_kernel_operation,
|
|
123
|
+
createdAt: new Date(row.created_at),
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
interface PgExecutionRow {
|
|
128
|
+
readonly project_id: string
|
|
129
|
+
readonly id: string
|
|
130
|
+
readonly executor_kind: ExecutionStorageRow["executorKind"]
|
|
131
|
+
readonly executor_id: string
|
|
132
|
+
readonly source_kind: ExecutionStorageRow["sourceKind"]
|
|
133
|
+
readonly source_id: string
|
|
134
|
+
readonly requested_by_user_id: string | null
|
|
135
|
+
readonly requested_by_service_account_id: string | null
|
|
136
|
+
readonly correlation_id: string
|
|
137
|
+
readonly parent_execution_id: string | null
|
|
138
|
+
readonly authority_kind: ExecutionStorageRow["authorityKind"]
|
|
139
|
+
readonly authority_user_id: string | null
|
|
140
|
+
readonly authority_service_account_id: string | null
|
|
141
|
+
readonly authority_session_id: string | null
|
|
142
|
+
readonly authority_access_token_id: string | null
|
|
143
|
+
readonly authority_primitive_kind: ExecutionStorageRow["authorityPrimitiveKind"]
|
|
144
|
+
readonly authority_primitive_id: string | null
|
|
145
|
+
readonly authority_kernel_operation: ExecutionStorageRow["authorityKernelOperation"]
|
|
146
|
+
readonly created_at: Date | string
|
|
147
|
+
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import type { JsonValue } from "@sixb/core"
|
|
2
|
+
import { parseSixbFailure, serializeSixbFailure } from "@sixb/core/internal/errors"
|
|
3
|
+
import { assertPipelineRunExecution } from "@sixb/core/internal/pipeline-run-storage-provider"
|
|
1
4
|
import type { DatasetVersionRef } from "@sixb/core/lake-storage"
|
|
2
5
|
import type {
|
|
6
|
+
ExecutionStorage,
|
|
3
7
|
FinishPipelineRunInput,
|
|
4
8
|
FinishPipelineStepRunInput,
|
|
5
9
|
ListLatestPipelineRunsInput,
|
|
@@ -8,14 +12,18 @@ import type {
|
|
|
8
12
|
ListPipelineRunsResult,
|
|
9
13
|
ListPipelineStepRunsInput,
|
|
10
14
|
ListPipelineStepRunsResult,
|
|
11
|
-
PipelineRunFailure,
|
|
12
15
|
PipelineRunRecord,
|
|
13
16
|
PipelineRunStorage,
|
|
14
17
|
PipelineStepRunRecord,
|
|
18
|
+
QueuePipelineRunInput,
|
|
15
19
|
StartPipelineRunInput,
|
|
16
20
|
StartPipelineStepRunInput,
|
|
17
21
|
} from "@sixb/core/storage"
|
|
18
|
-
import {
|
|
22
|
+
import {
|
|
23
|
+
canRequeuePipelineRunAfterEnqueueFailure,
|
|
24
|
+
PIPELINE_RUN_FAILURE_CODES,
|
|
25
|
+
PipelineRunError,
|
|
26
|
+
} from "@sixb/core/storage"
|
|
19
27
|
import { queryLatestRunsByOwnerId } from "./latest-run-query"
|
|
20
28
|
import type { SqlParameter } from "./pg-client"
|
|
21
29
|
import { appendRunListFilters, hasEmptyStatuses, queryRunList } from "./run-list-query"
|
|
@@ -23,23 +31,37 @@ import { isUniqueViolation } from "./storage-errors"
|
|
|
23
31
|
import { type PgStoreClient, runPgTransaction } from "./transactions"
|
|
24
32
|
|
|
25
33
|
export class PgPipelineRunStorage implements PipelineRunStorage {
|
|
26
|
-
constructor(
|
|
27
|
-
|
|
28
|
-
|
|
34
|
+
constructor(
|
|
35
|
+
private readonly sql: PgStoreClient,
|
|
36
|
+
private readonly executions: ExecutionStorage
|
|
37
|
+
) {}
|
|
38
|
+
|
|
39
|
+
async queue(input: QueuePipelineRunInput): Promise<PipelineRunRecord> {
|
|
40
|
+
await assertPipelineRunExecution({
|
|
41
|
+
executions: this.executions,
|
|
42
|
+
projectId: input.projectId,
|
|
43
|
+
executionId: input.executionId,
|
|
44
|
+
runId: input.id,
|
|
45
|
+
pipelineId: input.pipelineId,
|
|
46
|
+
})
|
|
29
47
|
try {
|
|
30
48
|
const [row] = await this.sql<PipelineRunDatabaseRow[]>`
|
|
31
49
|
INSERT INTO pipeline_runs (
|
|
32
50
|
project_id,
|
|
33
51
|
id,
|
|
52
|
+
execution_id,
|
|
34
53
|
pipeline_id,
|
|
35
54
|
status,
|
|
55
|
+
queued_at,
|
|
36
56
|
started_at
|
|
37
57
|
) VALUES (
|
|
38
58
|
${input.projectId},
|
|
39
59
|
${input.id},
|
|
60
|
+
${input.executionId},
|
|
40
61
|
${input.pipelineId},
|
|
41
|
-
${"
|
|
42
|
-
${input.
|
|
62
|
+
${"queued"},
|
|
63
|
+
${input.queuedAt ?? new Date()},
|
|
64
|
+
${null}
|
|
43
65
|
)
|
|
44
66
|
RETURNING *
|
|
45
67
|
`
|
|
@@ -47,13 +69,62 @@ export class PgPipelineRunStorage implements PipelineRunStorage {
|
|
|
47
69
|
return rowToPipelineRunRecord(row)
|
|
48
70
|
} catch (error) {
|
|
49
71
|
if (isUniqueViolation(error)) {
|
|
72
|
+
return this.requeueAfterEnqueueFailure(input)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
throw error
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private async requeueAfterEnqueueFailure(
|
|
80
|
+
input: QueuePipelineRunInput
|
|
81
|
+
): Promise<PipelineRunRecord> {
|
|
82
|
+
return runPgTransaction(this.sql, async (tx) => {
|
|
83
|
+
const [existing] = await tx<PipelineRunDatabaseRow[]>`
|
|
84
|
+
SELECT * FROM pipeline_runs
|
|
85
|
+
WHERE project_id = ${input.projectId} AND id = ${input.id}
|
|
86
|
+
FOR UPDATE
|
|
87
|
+
`
|
|
88
|
+
if (
|
|
89
|
+
!existing ||
|
|
90
|
+
!canRequeuePipelineRunAfterEnqueueFailure(rowToPipelineRunRecord(existing), input)
|
|
91
|
+
) {
|
|
50
92
|
throw new PipelineRunError(
|
|
51
93
|
`[SixbPg] Pipeline run '${input.id}' already exists for project '${input.projectId}'.`
|
|
52
94
|
)
|
|
53
95
|
}
|
|
54
96
|
|
|
55
|
-
|
|
97
|
+
const [updated] = await tx<PipelineRunDatabaseRow[]>`
|
|
98
|
+
UPDATE pipeline_runs
|
|
99
|
+
SET status = ${"queued"}, queued_at = ${input.queuedAt ?? new Date()},
|
|
100
|
+
started_at = ${null}, finished_at = ${null}, output_dataset_id = ${null},
|
|
101
|
+
output_version_id = ${null}, error = ${null}
|
|
102
|
+
WHERE project_id = ${input.projectId} AND id = ${input.id}
|
|
103
|
+
RETURNING *
|
|
104
|
+
`
|
|
105
|
+
return rowToPipelineRunRecord(updated)
|
|
106
|
+
})
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async start(input: StartPipelineRunInput): Promise<PipelineRunRecord> {
|
|
110
|
+
const [updated] = await this.sql<PipelineRunDatabaseRow[]>`
|
|
111
|
+
UPDATE pipeline_runs
|
|
112
|
+
SET status = ${"running"}, started_at = ${input.startedAt ?? new Date()},
|
|
113
|
+
error = ${null}
|
|
114
|
+
WHERE project_id = ${input.projectId} AND id = ${input.id} AND status = ${"queued"}
|
|
115
|
+
RETURNING *
|
|
116
|
+
`
|
|
117
|
+
if (updated) return rowToPipelineRunRecord(updated)
|
|
118
|
+
|
|
119
|
+
const existing = await this.getById({ projectId: input.projectId, id: input.id })
|
|
120
|
+
if (!existing) {
|
|
121
|
+
throw new PipelineRunError(
|
|
122
|
+
`[SixbPg] Pipeline run '${input.id}' not found for project '${input.projectId}'.`
|
|
123
|
+
)
|
|
56
124
|
}
|
|
125
|
+
throw new PipelineRunError(
|
|
126
|
+
`[SixbPg] Pipeline run '${input.id}' cannot start from status '${existing.status}'.`
|
|
127
|
+
)
|
|
57
128
|
}
|
|
58
129
|
|
|
59
130
|
async finish(input: FinishPipelineRunInput): Promise<PipelineRunRecord> {
|
|
@@ -69,9 +140,14 @@ export class PgPipelineRunStorage implements PipelineRunStorage {
|
|
|
69
140
|
)
|
|
70
141
|
}
|
|
71
142
|
|
|
72
|
-
|
|
143
|
+
const enqueueFailure =
|
|
144
|
+
input.status === "failed" && input.error.code === "queue.enqueue_failed"
|
|
145
|
+
if (
|
|
146
|
+
(enqueueFailure && existing.status !== "queued") ||
|
|
147
|
+
(!enqueueFailure && existing.status !== "running")
|
|
148
|
+
) {
|
|
73
149
|
throw new PipelineRunError(
|
|
74
|
-
`[SixbPg] Pipeline run '${input.id}'
|
|
150
|
+
`[SixbPg] Pipeline run '${input.id}' cannot finish from status '${existing.status}'.`
|
|
75
151
|
)
|
|
76
152
|
}
|
|
77
153
|
|
|
@@ -84,8 +160,7 @@ export class PgPipelineRunStorage implements PipelineRunStorage {
|
|
|
84
160
|
finished_at = ${input.finishedAt ?? new Date()},
|
|
85
161
|
output_dataset_id = ${input.output?.datasetId ?? null},
|
|
86
162
|
output_version_id = ${input.output?.versionId ?? null},
|
|
87
|
-
|
|
88
|
-
error_message = ${null}
|
|
163
|
+
error = ${null}
|
|
89
164
|
WHERE project_id = ${input.projectId} AND id = ${input.id}
|
|
90
165
|
RETURNING *
|
|
91
166
|
`
|
|
@@ -96,8 +171,7 @@ export class PgPipelineRunStorage implements PipelineRunStorage {
|
|
|
96
171
|
finished_at = ${input.finishedAt ?? new Date()},
|
|
97
172
|
output_dataset_id = ${null},
|
|
98
173
|
output_version_id = ${null},
|
|
99
|
-
|
|
100
|
-
error_message = ${input.error?.message ?? null}
|
|
174
|
+
error = ${input.error === undefined ? null : serializeSixbFailure(input.error, PIPELINE_RUN_FAILURE_CODES)}::text::jsonb
|
|
101
175
|
WHERE project_id = ${input.projectId} AND id = ${input.id}
|
|
102
176
|
RETURNING *
|
|
103
177
|
`
|
|
@@ -208,8 +282,7 @@ export class PgPipelineRunStorage implements PipelineRunStorage {
|
|
|
208
282
|
finished_at = ${input.finishedAt ?? new Date()},
|
|
209
283
|
output_version_id = ${input.output.versionId},
|
|
210
284
|
rows_written = ${input.rowsWritten ?? existing.rows_written ?? null},
|
|
211
|
-
|
|
212
|
-
error_message = ${null}
|
|
285
|
+
error = ${null}
|
|
213
286
|
WHERE project_id = ${input.projectId} AND id = ${input.id}
|
|
214
287
|
RETURNING *
|
|
215
288
|
`
|
|
@@ -220,8 +293,7 @@ export class PgPipelineRunStorage implements PipelineRunStorage {
|
|
|
220
293
|
finished_at = ${input.finishedAt ?? new Date()},
|
|
221
294
|
output_version_id = ${null},
|
|
222
295
|
rows_written = ${input.rowsWritten ?? existing.rows_written ?? null},
|
|
223
|
-
|
|
224
|
-
error_message = ${input.error?.message ?? null}
|
|
296
|
+
error = ${input.error === undefined ? null : serializeSixbFailure(input.error, PIPELINE_RUN_FAILURE_CODES)}::text::jsonb
|
|
225
297
|
WHERE project_id = ${input.projectId} AND id = ${input.id}
|
|
226
298
|
RETURNING *
|
|
227
299
|
`
|
|
@@ -263,7 +335,13 @@ export class PgPipelineRunStorage implements PipelineRunStorage {
|
|
|
263
335
|
params.push(...input.pipelineIds)
|
|
264
336
|
}
|
|
265
337
|
|
|
266
|
-
index = appendRunListFilters(
|
|
338
|
+
index = appendRunListFilters(
|
|
339
|
+
whereClauses,
|
|
340
|
+
params,
|
|
341
|
+
index,
|
|
342
|
+
input,
|
|
343
|
+
"COALESCE(started_at, queued_at)"
|
|
344
|
+
)
|
|
267
345
|
|
|
268
346
|
const { rows, total, hasMore } = await queryRunList<PipelineRunDatabaseRow>({
|
|
269
347
|
sql: this.sql,
|
|
@@ -356,27 +434,15 @@ export class PgPipelineRunStorage implements PipelineRunStorage {
|
|
|
356
434
|
}
|
|
357
435
|
}
|
|
358
436
|
|
|
359
|
-
function toFailure(row: {
|
|
360
|
-
readonly error_name: string | null
|
|
361
|
-
readonly error_message: string | null
|
|
362
|
-
}): PipelineRunFailure | undefined {
|
|
363
|
-
if (!row.error_message) {
|
|
364
|
-
return undefined
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
return {
|
|
368
|
-
name: row.error_name ?? undefined,
|
|
369
|
-
message: row.error_message,
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
|
|
373
437
|
function rowToPipelineRunRecord(row: PipelineRunDatabaseRow): PipelineRunRecord {
|
|
374
438
|
return {
|
|
375
439
|
id: row.id,
|
|
376
440
|
projectId: row.project_id,
|
|
441
|
+
executionId: row.execution_id,
|
|
377
442
|
pipelineId: row.pipeline_id,
|
|
378
443
|
status: row.status,
|
|
379
|
-
|
|
444
|
+
queuedAt: new Date(row.queued_at),
|
|
445
|
+
startedAt: row.started_at ? new Date(row.started_at) : undefined,
|
|
380
446
|
finishedAt: row.finished_at ? new Date(row.finished_at) : undefined,
|
|
381
447
|
output:
|
|
382
448
|
row.output_dataset_id && row.output_version_id
|
|
@@ -385,7 +451,7 @@ function rowToPipelineRunRecord(row: PipelineRunDatabaseRow): PipelineRunRecord
|
|
|
385
451
|
versionId: row.output_version_id,
|
|
386
452
|
}
|
|
387
453
|
: undefined,
|
|
388
|
-
error:
|
|
454
|
+
error: row.error === null ? undefined : parseSixbFailure(row.error, PIPELINE_RUN_FAILURE_CODES),
|
|
389
455
|
}
|
|
390
456
|
}
|
|
391
457
|
|
|
@@ -409,7 +475,7 @@ function rowToPipelineStepRunRecord(row: PipelineStepRunDatabaseRow): PipelineSt
|
|
|
409
475
|
}
|
|
410
476
|
: undefined,
|
|
411
477
|
rowsWritten: row.rows_written != null ? Number(row.rows_written) : undefined,
|
|
412
|
-
error:
|
|
478
|
+
error: row.error === null ? undefined : parseSixbFailure(row.error, PIPELINE_RUN_FAILURE_CODES),
|
|
413
479
|
}
|
|
414
480
|
}
|
|
415
481
|
|
|
@@ -428,14 +494,15 @@ function assertOptionalNonNegativeInteger(value: number | undefined, fieldName:
|
|
|
428
494
|
interface PipelineRunDatabaseRow {
|
|
429
495
|
project_id: string
|
|
430
496
|
id: string
|
|
497
|
+
execution_id: string
|
|
431
498
|
pipeline_id: string
|
|
432
499
|
status: PipelineRunRecord["status"]
|
|
433
|
-
|
|
500
|
+
queued_at: Date | string
|
|
501
|
+
started_at: Date | string | null
|
|
434
502
|
finished_at: Date | string | null
|
|
435
503
|
output_dataset_id: string | null
|
|
436
504
|
output_version_id: string | null
|
|
437
|
-
|
|
438
|
-
error_message: string | null
|
|
505
|
+
error: JsonValue | null
|
|
439
506
|
}
|
|
440
507
|
|
|
441
508
|
interface PipelineStepRunDatabaseRow {
|
|
@@ -452,6 +519,5 @@ interface PipelineStepRunDatabaseRow {
|
|
|
452
519
|
inputs: readonly DatasetVersionRef[] | string
|
|
453
520
|
output_version_id: string | null
|
|
454
521
|
rows_written: number | string | null
|
|
455
|
-
|
|
456
|
-
error_message: string | null
|
|
522
|
+
error: JsonValue | null
|
|
457
523
|
}
|