mirror of
https://gh-proxy.org/https://github.com/klinsmaya/multica.git
synced 2026-11-08 01:16:45 +08:00
306 lines
9.8 KiB
Go
306 lines
9.8 KiB
Go
// Code generated by sqlc. DO NOT EDIT.
|
|
// versions:
|
|
// sqlc v1.31.1
|
|
// source: task_message.sql
|
|
|
|
package db
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
)
|
|
|
|
const createTaskMessage = `-- name: CreateTaskMessage :one
|
|
INSERT INTO task_message (id, task_id, seq, type, tool, content, input, output, output_truncated, call_id)
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
|
|
RETURNING id, task_id, seq, type, tool, content, input, output, created_at, output_truncated, call_id
|
|
`
|
|
|
|
type CreateTaskMessageParams struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
TaskID pgtype.UUID `json:"task_id"`
|
|
Seq int32 `json:"seq"`
|
|
Type string `json:"type"`
|
|
Tool pgtype.Text `json:"tool"`
|
|
Content pgtype.Text `json:"content"`
|
|
Input []byte `json:"input"`
|
|
Output pgtype.Text `json:"output"`
|
|
OutputTruncated pgtype.Bool `json:"output_truncated"`
|
|
CallID pgtype.Text `json:"call_id"`
|
|
}
|
|
|
|
func (q *Queries) CreateTaskMessage(ctx context.Context, arg CreateTaskMessageParams) (TaskMessage, error) {
|
|
row := q.db.QueryRow(ctx, createTaskMessage,
|
|
arg.ID,
|
|
arg.TaskID,
|
|
arg.Seq,
|
|
arg.Type,
|
|
arg.Tool,
|
|
arg.Content,
|
|
arg.Input,
|
|
arg.Output,
|
|
arg.OutputTruncated,
|
|
arg.CallID,
|
|
)
|
|
var i TaskMessage
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.TaskID,
|
|
&i.Seq,
|
|
&i.Type,
|
|
&i.Tool,
|
|
&i.Content,
|
|
&i.Input,
|
|
&i.Output,
|
|
&i.CreatedAt,
|
|
&i.OutputTruncated,
|
|
&i.CallID,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const createTaskMessages = `-- name: CreateTaskMessages :many
|
|
WITH incoming AS (
|
|
-- Several single-argument unnest calls in one SELECT list expand in
|
|
-- lockstep (PostgreSQL 10+ set-returning-function semantics), which is the
|
|
-- same row-wise zip the multi-argument unnest(a, b, ...) form gives — but
|
|
-- sqlc's analyzer only knows the single-argument signature, so this is the
|
|
-- shape that survives code generation.
|
|
SELECT
|
|
unnest($1::uuid[]) AS id,
|
|
unnest($2::int4[]) AS seq,
|
|
unnest($3::text[]) AS type,
|
|
unnest($4::text[]) AS tool,
|
|
unnest($5::text[]) AS call_id,
|
|
unnest($6::text[]) AS content,
|
|
unnest($7::text[]) AS input,
|
|
unnest($8::text[]) AS output,
|
|
unnest($9::text[]) AS created_at,
|
|
unnest($10::text[]) AS output_truncated
|
|
), inserted AS (
|
|
INSERT INTO task_message (id, task_id, seq, type, tool, content, input, output, created_at, output_truncated, call_id)
|
|
SELECT
|
|
m.id,
|
|
$11::uuid,
|
|
m.seq,
|
|
m.type,
|
|
NULLIF(m.tool, ''),
|
|
NULLIF(m.content, ''),
|
|
NULLIF(m.input, '')::jsonb,
|
|
NULLIF(m.output, ''),
|
|
COALESCE(NULLIF(m.created_at, '')::timestamptz, now()),
|
|
NULLIF(m.output_truncated, '')::bool,
|
|
NULLIF(m.call_id, '')
|
|
FROM incoming AS m
|
|
RETURNING id, task_id, seq, type, tool, content, input, output, created_at, output_truncated, call_id
|
|
)
|
|
SELECT id, task_id, seq, type, tool, content, input, output, created_at, output_truncated, call_id FROM inserted ORDER BY seq ASC
|
|
`
|
|
|
|
type CreateTaskMessagesParams struct {
|
|
Ids []pgtype.UUID `json:"ids"`
|
|
Seqs []int32 `json:"seqs"`
|
|
Types []string `json:"types"`
|
|
Tools []string `json:"tools"`
|
|
CallIds []string `json:"call_ids"`
|
|
Contents []string `json:"contents"`
|
|
Inputs []string `json:"inputs"`
|
|
Outputs []string `json:"outputs"`
|
|
CreatedAts []string `json:"created_ats"`
|
|
OutputTruncations []string `json:"output_truncations"`
|
|
TaskID pgtype.UUID `json:"task_id"`
|
|
}
|
|
|
|
type CreateTaskMessagesRow struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
TaskID pgtype.UUID `json:"task_id"`
|
|
Seq int32 `json:"seq"`
|
|
Type string `json:"type"`
|
|
Tool pgtype.Text `json:"tool"`
|
|
Content pgtype.Text `json:"content"`
|
|
Input []byte `json:"input"`
|
|
Output pgtype.Text `json:"output"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
OutputTruncated pgtype.Bool `json:"output_truncated"`
|
|
CallID pgtype.Text `json:"call_id"`
|
|
}
|
|
|
|
// Batch variant of CreateTaskMessage: persists a whole daemon-reported batch in
|
|
// ONE statement — therefore one round trip and, more importantly, one commit
|
|
// instead of one per message. Commit acknowledgement (IO:XactSync) is ~94% of
|
|
// this SQL's load in production, so the commit count is the thing being
|
|
// optimized; the round trip is a bonus.
|
|
//
|
|
// The rows arrive as parallel arrays rather than as one jsonb document, even
|
|
// though a jsonb document is the tidier Go side. content and output routinely
|
|
// carry tens of KB and occasionally megabytes, and wrapping them in JSON makes
|
|
// the server escape every byte a second time and Postgres parse the whole
|
|
// envelope back out — measured at 1.2x the old per-row insert at 128KB and
|
|
// ~1.8x at 1MB, i.e. a regression on exactly the most expensive requests, which
|
|
// are also the ones least likely to be batched. Native text[] elements are
|
|
// length-prefixed by the wire protocol, so they cost neither pass.
|
|
//
|
|
// NULLIF is what makes per-row NULL expressible through a non-nullable []string
|
|
// (the Go type sqlc gives a text[] parameter): it reproduces, exactly, the
|
|
// `pgtype.Text{Valid: x != ""}` mapping the single-row query carries — empty
|
|
// string means SQL NULL. input is passed as text and cast here for the same
|
|
// reason; it is the one column that genuinely has to be parsed as JSON, because
|
|
// it is a jsonb column. created_at also rides this transport so an older daemon
|
|
// can omit its event time and keep the database-time fallback. output_truncated
|
|
// uses the same trick because it is a genuinely tri-state boolean (NULL = the
|
|
// reporting daemon did not measure it), and a bool[] parameter becomes a Go
|
|
// []bool, which has no way to spell the third state.
|
|
//
|
|
// Callers MUST still run the Postgres text sanitizer first. A NUL anywhere in
|
|
// the batch fails the whole statement (GH #7098) — that is inherent to batching
|
|
// into one statement, not to the parameter shape.
|
|
//
|
|
// Atomicity is a deliberate side effect, not just a speedup: the per-message
|
|
// loop this replaces could persist part of a batch and then fail, leaving the
|
|
// transcript with a prefix of the batch and no way to complete it — the daemon
|
|
// does not retry this endpoint. One statement makes the batch all-or-nothing,
|
|
// which buys consistency; a batch that fails is still lost whole, so closing
|
|
// the gap for real needs a retry plus a (task_id, seq) uniqueness rule.
|
|
//
|
|
// The ORDER BY is a contract, not decoration. A bare `INSERT ... RETURNING`
|
|
// has no defined row order, and the caller republishes these rows as realtime
|
|
// events in the order they arrive — the per-row loop this replaces implicitly
|
|
// published in request order, so the ordering has to be restored explicitly or
|
|
// subscribers can see a batch out of order. seq is assigned by the daemon and
|
|
// increases within a batch, so it is the request order.
|
|
func (q *Queries) CreateTaskMessages(ctx context.Context, arg CreateTaskMessagesParams) ([]CreateTaskMessagesRow, error) {
|
|
rows, err := q.db.Query(ctx, createTaskMessages,
|
|
arg.Ids,
|
|
arg.Seqs,
|
|
arg.Types,
|
|
arg.Tools,
|
|
arg.CallIds,
|
|
arg.Contents,
|
|
arg.Inputs,
|
|
arg.Outputs,
|
|
arg.CreatedAts,
|
|
arg.OutputTruncations,
|
|
arg.TaskID,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
items := []CreateTaskMessagesRow{}
|
|
for rows.Next() {
|
|
var i CreateTaskMessagesRow
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.TaskID,
|
|
&i.Seq,
|
|
&i.Type,
|
|
&i.Tool,
|
|
&i.Content,
|
|
&i.Input,
|
|
&i.Output,
|
|
&i.CreatedAt,
|
|
&i.OutputTruncated,
|
|
&i.CallID,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const deleteTaskMessages = `-- name: DeleteTaskMessages :exec
|
|
DELETE FROM task_message
|
|
WHERE task_id = $1
|
|
`
|
|
|
|
func (q *Queries) DeleteTaskMessages(ctx context.Context, taskID pgtype.UUID) error {
|
|
_, err := q.db.Exec(ctx, deleteTaskMessages, taskID)
|
|
return err
|
|
}
|
|
|
|
const listTaskMessages = `-- name: ListTaskMessages :many
|
|
SELECT id, task_id, seq, type, tool, content, input, output, created_at, output_truncated, call_id FROM task_message
|
|
WHERE task_id = $1
|
|
ORDER BY seq ASC
|
|
`
|
|
|
|
func (q *Queries) ListTaskMessages(ctx context.Context, taskID pgtype.UUID) ([]TaskMessage, error) {
|
|
rows, err := q.db.Query(ctx, listTaskMessages, taskID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
items := []TaskMessage{}
|
|
for rows.Next() {
|
|
var i TaskMessage
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.TaskID,
|
|
&i.Seq,
|
|
&i.Type,
|
|
&i.Tool,
|
|
&i.Content,
|
|
&i.Input,
|
|
&i.Output,
|
|
&i.CreatedAt,
|
|
&i.OutputTruncated,
|
|
&i.CallID,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const listTaskMessagesSince = `-- name: ListTaskMessagesSince :many
|
|
SELECT id, task_id, seq, type, tool, content, input, output, created_at, output_truncated, call_id FROM task_message
|
|
WHERE task_id = $1 AND seq > $2
|
|
ORDER BY seq ASC
|
|
`
|
|
|
|
type ListTaskMessagesSinceParams struct {
|
|
TaskID pgtype.UUID `json:"task_id"`
|
|
Seq int32 `json:"seq"`
|
|
}
|
|
|
|
func (q *Queries) ListTaskMessagesSince(ctx context.Context, arg ListTaskMessagesSinceParams) ([]TaskMessage, error) {
|
|
rows, err := q.db.Query(ctx, listTaskMessagesSince, arg.TaskID, arg.Seq)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
items := []TaskMessage{}
|
|
for rows.Next() {
|
|
var i TaskMessage
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.TaskID,
|
|
&i.Seq,
|
|
&i.Type,
|
|
&i.Tool,
|
|
&i.Content,
|
|
&i.Input,
|
|
&i.Output,
|
|
&i.CreatedAt,
|
|
&i.OutputTruncated,
|
|
&i.CallID,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|