// Code generated by sqlc. DO NOT EDIT.
// versions:
//   sqlc v1.29.0
// source: durable_event_log.sql

package sqlcv1

import (
	"context"

	"github.com/google/uuid"
	"github.com/jackc/pgx/v5/pgtype"
)

const bulkCreateDurableEventLogEntries = `-- name: BulkCreateDurableEventLogEntries :many
WITH inputs AS (
    SELECT
        UNNEST($1::UUID[]) AS tenant_id,
        UNNEST($2::UUID[]) AS external_id,
        UNNEST($3::UUID[]) AS child_task_external_id,
        UNNEST($4::BIGINT[]) AS durable_task_id,
        UNNEST($5::TIMESTAMPTZ[]) AS durable_task_inserted_at,
        UNNEST($6::text[]) AS kind,
        UNNEST($7::BIGINT[]) AS node_id,
        UNNEST($8::BIGINT[]) AS branch_id,
        UNNEST($9::BYTEA[]) AS idempotency_key,
        UNNEST($10::BOOLEAN[]) AS is_satisfied,
        UNNEST($11::TEXT[]) AS user_message,
        UNNEST($12::TEXT[]) AS wait_data
), inserts AS (
    INSERT INTO v1_durable_event_log_entry (
        tenant_id,
        external_id,
        child_task_external_id,
        durable_task_id,
        durable_task_inserted_at,
        inserted_at,
        kind,
        node_id,
        branch_id,
        idempotency_key,
        is_satisfied,
        user_message,
        wait_data
    )
    SELECT
        i.tenant_id,
        i.external_id,
        NULLIF(i.child_task_external_id, '00000000-0000-0000-0000-000000000000'::UUID),
        i.durable_task_id,
        i.durable_task_inserted_at,
        NOW(),
        i.kind::v1_durable_event_log_kind,
        i.node_id,
        i.branch_id,
        i.idempotency_key,
        i.is_satisfied,
        NULLIF(i.user_message, ''),
        CASE WHEN i.wait_data = '' THEN NULL ELSE i.wait_data::JSONB END
    FROM inputs i
    ON CONFLICT (durable_task_id, durable_task_inserted_at, branch_id, node_id) DO NOTHING
    RETURNING tenant_id, external_id, result_payload_external_id, child_task_external_id, inserted_at, id, durable_task_id, durable_task_inserted_at, kind, node_id, branch_id, idempotency_key, is_satisfied, satisfied_at, user_message, wait_data
)

SELECT i.tenant_id, i.external_id, i.result_payload_external_id, i.child_task_external_id, i.inserted_at, i.id, i.durable_task_id, i.durable_task_inserted_at, i.kind, i.node_id, i.branch_id, i.idempotency_key, i.is_satisfied, i.satisfied_at, i.user_message, i.wait_data, lf.latest_invocation_count AS invocation_count
FROM inserts i
JOIN v1_durable_event_log_file lf ON (lf.durable_task_id, lf.durable_task_inserted_at) = (i.durable_task_id, i.durable_task_inserted_at)
`

type BulkCreateDurableEventLogEntriesParams struct {
	Tenantids              []uuid.UUID          `json:"tenantids"`
	Externalids            []uuid.UUID          `json:"externalids"`
	Childtaskexternalids   []uuid.UUID          `json:"childtaskexternalids"`
	Durabletaskids         []int64              `json:"durabletaskids"`
	Durabletaskinsertedats []pgtype.Timestamptz `json:"durabletaskinsertedats"`
	Kinds                  []string             `json:"kinds"`
	Nodeids                []int64              `json:"nodeids"`
	Branchids              []int64              `json:"branchids"`
	Idempotencykeys        [][]byte             `json:"idempotencykeys"`
	Issatisfieds           []bool               `json:"issatisfieds"`
	Usermessages           []string             `json:"usermessages"`
	Waitdatas              []string             `json:"waitdatas"`
}

type BulkCreateDurableEventLogEntriesRow struct {
	TenantID                uuid.UUID             `json:"tenant_id"`
	ExternalID              uuid.UUID             `json:"external_id"`
	ResultPayloadExternalID uuid.UUID             `json:"result_payload_external_id"`
	ChildTaskExternalID     *uuid.UUID            `json:"child_task_external_id"`
	InsertedAt              pgtype.Timestamptz    `json:"inserted_at"`
	ID                      int64                 `json:"id"`
	DurableTaskID           int64                 `json:"durable_task_id"`
	DurableTaskInsertedAt   pgtype.Timestamptz    `json:"durable_task_inserted_at"`
	Kind                    V1DurableEventLogKind `json:"kind"`
	NodeID                  int64                 `json:"node_id"`
	BranchID                int64                 `json:"branch_id"`
	IdempotencyKey          []byte                `json:"idempotency_key"`
	IsSatisfied             bool                  `json:"is_satisfied"`
	SatisfiedAt             pgtype.Timestamptz    `json:"satisfied_at"`
	UserMessage             pgtype.Text           `json:"user_message"`
	WaitData                []byte                `json:"wait_data"`
	InvocationCount         int32                 `json:"invocation_count"`
}

func (q *Queries) BulkCreateDurableEventLogEntries(ctx context.Context, db DBTX, arg BulkCreateDurableEventLogEntriesParams) ([]*BulkCreateDurableEventLogEntriesRow, error) {
	rows, err := db.Query(ctx, bulkCreateDurableEventLogEntries,
		arg.Tenantids,
		arg.Externalids,
		arg.Childtaskexternalids,
		arg.Durabletaskids,
		arg.Durabletaskinsertedats,
		arg.Kinds,
		arg.Nodeids,
		arg.Branchids,
		arg.Idempotencykeys,
		arg.Issatisfieds,
		arg.Usermessages,
		arg.Waitdatas,
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*BulkCreateDurableEventLogEntriesRow
	for rows.Next() {
		var i BulkCreateDurableEventLogEntriesRow
		if err := rows.Scan(
			&i.TenantID,
			&i.ExternalID,
			&i.ResultPayloadExternalID,
			&i.ChildTaskExternalID,
			&i.InsertedAt,
			&i.ID,
			&i.DurableTaskID,
			&i.DurableTaskInsertedAt,
			&i.Kind,
			&i.NodeID,
			&i.BranchID,
			&i.IdempotencyKey,
			&i.IsSatisfied,
			&i.SatisfiedAt,
			&i.UserMessage,
			&i.WaitData,
			&i.InvocationCount,
		); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const bulkGetDurableEventLogEntries = `-- name: BulkGetDurableEventLogEntries :many
WITH inputs AS (
    SELECT
        UNNEST($3::BIGINT[]) AS branch_id,
        UNNEST($4::BIGINT[]) AS node_id
)
SELECT e.tenant_id, e.external_id, e.result_payload_external_id, e.child_task_external_id, e.inserted_at, e.id, e.durable_task_id, e.durable_task_inserted_at, e.kind, e.node_id, e.branch_id, e.idempotency_key, e.is_satisfied, e.satisfied_at, e.user_message, e.wait_data, lf.latest_invocation_count AS invocation_count
FROM v1_durable_event_log_entry e
JOIN inputs i ON e.branch_id = i.branch_id AND e.node_id = i.node_id
JOIN v1_durable_event_log_file lf ON (lf.durable_task_id, lf.durable_task_inserted_at) = (e.durable_task_id, e.durable_task_inserted_at)
WHERE e.durable_task_id = $1::BIGINT
  AND e.durable_task_inserted_at = $2::TIMESTAMPTZ
`

type BulkGetDurableEventLogEntriesParams struct {
	Durabletaskid         int64              `json:"durabletaskid"`
	Durabletaskinsertedat pgtype.Timestamptz `json:"durabletaskinsertedat"`
	Branchids             []int64            `json:"branchids"`
	Nodeids               []int64            `json:"nodeids"`
}

type BulkGetDurableEventLogEntriesRow struct {
	TenantID                uuid.UUID             `json:"tenant_id"`
	ExternalID              uuid.UUID             `json:"external_id"`
	ResultPayloadExternalID uuid.UUID             `json:"result_payload_external_id"`
	ChildTaskExternalID     *uuid.UUID            `json:"child_task_external_id"`
	InsertedAt              pgtype.Timestamptz    `json:"inserted_at"`
	ID                      int64                 `json:"id"`
	DurableTaskID           int64                 `json:"durable_task_id"`
	DurableTaskInsertedAt   pgtype.Timestamptz    `json:"durable_task_inserted_at"`
	Kind                    V1DurableEventLogKind `json:"kind"`
	NodeID                  int64                 `json:"node_id"`
	BranchID                int64                 `json:"branch_id"`
	IdempotencyKey          []byte                `json:"idempotency_key"`
	IsSatisfied             bool                  `json:"is_satisfied"`
	SatisfiedAt             pgtype.Timestamptz    `json:"satisfied_at"`
	UserMessage             pgtype.Text           `json:"user_message"`
	WaitData                []byte                `json:"wait_data"`
	InvocationCount         int32                 `json:"invocation_count"`
}

func (q *Queries) BulkGetDurableEventLogEntries(ctx context.Context, db DBTX, arg BulkGetDurableEventLogEntriesParams) ([]*BulkGetDurableEventLogEntriesRow, error) {
	rows, err := db.Query(ctx, bulkGetDurableEventLogEntries,
		arg.Durabletaskid,
		arg.Durabletaskinsertedat,
		arg.Branchids,
		arg.Nodeids,
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*BulkGetDurableEventLogEntriesRow
	for rows.Next() {
		var i BulkGetDurableEventLogEntriesRow
		if err := rows.Scan(
			&i.TenantID,
			&i.ExternalID,
			&i.ResultPayloadExternalID,
			&i.ChildTaskExternalID,
			&i.InsertedAt,
			&i.ID,
			&i.DurableTaskID,
			&i.DurableTaskInsertedAt,
			&i.Kind,
			&i.NodeID,
			&i.BranchID,
			&i.IdempotencyKey,
			&i.IsSatisfied,
			&i.SatisfiedAt,
			&i.UserMessage,
			&i.WaitData,
			&i.InvocationCount,
		); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const createDurableEventLogBranchPoint = `-- name: CreateDurableEventLogBranchPoint :exec
INSERT INTO v1_durable_event_log_branch_point (
    tenant_id,
    durable_task_id,
    durable_task_inserted_at,
    first_node_id_in_new_branch,
    parent_branch_id,
    next_branch_id
)
VALUES (
    $1::UUID,
    $2::BIGINT,
    $3::TIMESTAMPTZ,
    $4::BIGINT,
    $5::BIGINT,
    $6::BIGINT
)
RETURNING tenant_id, id, inserted_at, durable_task_id, durable_task_inserted_at, first_node_id_in_new_branch, parent_branch_id, next_branch_id
`

type CreateDurableEventLogBranchPointParams struct {
	Tenantid               uuid.UUID          `json:"tenantid"`
	Durabletaskid          int64              `json:"durabletaskid"`
	Durabletaskinsertedat  pgtype.Timestamptz `json:"durabletaskinsertedat"`
	Firstnodeidinnewbranch int64              `json:"firstnodeidinnewbranch"`
	Parentbranchid         int64              `json:"parentbranchid"`
	Nextbranchid           int64              `json:"nextbranchid"`
}

func (q *Queries) CreateDurableEventLogBranchPoint(ctx context.Context, db DBTX, arg CreateDurableEventLogBranchPointParams) error {
	_, err := db.Exec(ctx, createDurableEventLogBranchPoint,
		arg.Tenantid,
		arg.Durabletaskid,
		arg.Durabletaskinsertedat,
		arg.Firstnodeidinnewbranch,
		arg.Parentbranchid,
		arg.Nextbranchid,
	)
	return err
}

const getAndLockLogFile = `-- name: GetAndLockLogFile :one
SELECT tenant_id, durable_task_id, durable_task_inserted_at, latest_invocation_count, latest_inserted_at, latest_node_id, latest_branch_id
FROM v1_durable_event_log_file
WHERE
    durable_task_id = $1::BIGINT
    AND durable_task_inserted_at = $2::TIMESTAMPTZ
    AND tenant_id = $3::UUID
FOR UPDATE
`

type GetAndLockLogFileParams struct {
	Durabletaskid         int64              `json:"durabletaskid"`
	Durabletaskinsertedat pgtype.Timestamptz `json:"durabletaskinsertedat"`
	Tenantid              uuid.UUID          `json:"tenantid"`
}

func (q *Queries) GetAndLockLogFile(ctx context.Context, db DBTX, arg GetAndLockLogFileParams) (*V1DurableEventLogFile, error) {
	row := db.QueryRow(ctx, getAndLockLogFile, arg.Durabletaskid, arg.Durabletaskinsertedat, arg.Tenantid)
	var i V1DurableEventLogFile
	err := row.Scan(
		&i.TenantID,
		&i.DurableTaskID,
		&i.DurableTaskInsertedAt,
		&i.LatestInvocationCount,
		&i.LatestInsertedAt,
		&i.LatestNodeID,
		&i.LatestBranchID,
	)
	return &i, err
}

const getDurableEventLogEntriesByChildTaskExternalIds = `-- name: GetDurableEventLogEntriesByChildTaskExternalIds :many
SELECT e.tenant_id, e.external_id, e.result_payload_external_id, e.child_task_external_id, e.inserted_at, e.id, e.durable_task_id, e.durable_task_inserted_at, e.kind, e.node_id, e.branch_id, e.idempotency_key, e.is_satisfied, e.satisfied_at, e.user_message, e.wait_data, lf.latest_invocation_count AS invocation_count
FROM v1_durable_event_log_entry e
JOIN v1_durable_event_log_file lf ON (lf.durable_task_id, lf.durable_task_inserted_at) = (e.durable_task_id, e.durable_task_inserted_at)
WHERE
    e.durable_task_id = $1::BIGINT
    AND e.durable_task_inserted_at = $2::TIMESTAMPTZ
    AND e.child_task_external_id = ANY($3::UUID[])
ORDER BY e.child_task_external_id, e.node_id ASC
`

type GetDurableEventLogEntriesByChildTaskExternalIdsParams struct {
	Durabletaskid         int64              `json:"durabletaskid"`
	Durabletaskinsertedat pgtype.Timestamptz `json:"durabletaskinsertedat"`
	Childtaskexternalids  []uuid.UUID        `json:"childtaskexternalids"`
}

type GetDurableEventLogEntriesByChildTaskExternalIdsRow struct {
	TenantID                uuid.UUID             `json:"tenant_id"`
	ExternalID              uuid.UUID             `json:"external_id"`
	ResultPayloadExternalID uuid.UUID             `json:"result_payload_external_id"`
	ChildTaskExternalID     *uuid.UUID            `json:"child_task_external_id"`
	InsertedAt              pgtype.Timestamptz    `json:"inserted_at"`
	ID                      int64                 `json:"id"`
	DurableTaskID           int64                 `json:"durable_task_id"`
	DurableTaskInsertedAt   pgtype.Timestamptz    `json:"durable_task_inserted_at"`
	Kind                    V1DurableEventLogKind `json:"kind"`
	NodeID                  int64                 `json:"node_id"`
	BranchID                int64                 `json:"branch_id"`
	IdempotencyKey          []byte                `json:"idempotency_key"`
	IsSatisfied             bool                  `json:"is_satisfied"`
	SatisfiedAt             pgtype.Timestamptz    `json:"satisfied_at"`
	UserMessage             pgtype.Text           `json:"user_message"`
	WaitData                []byte                `json:"wait_data"`
	InvocationCount         int32                 `json:"invocation_count"`
}

func (q *Queries) GetDurableEventLogEntriesByChildTaskExternalIds(ctx context.Context, db DBTX, arg GetDurableEventLogEntriesByChildTaskExternalIdsParams) ([]*GetDurableEventLogEntriesByChildTaskExternalIdsRow, error) {
	rows, err := db.Query(ctx, getDurableEventLogEntriesByChildTaskExternalIds, arg.Durabletaskid, arg.Durabletaskinsertedat, arg.Childtaskexternalids)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*GetDurableEventLogEntriesByChildTaskExternalIdsRow
	for rows.Next() {
		var i GetDurableEventLogEntriesByChildTaskExternalIdsRow
		if err := rows.Scan(
			&i.TenantID,
			&i.ExternalID,
			&i.ResultPayloadExternalID,
			&i.ChildTaskExternalID,
			&i.InsertedAt,
			&i.ID,
			&i.DurableTaskID,
			&i.DurableTaskInsertedAt,
			&i.Kind,
			&i.NodeID,
			&i.BranchID,
			&i.IdempotencyKey,
			&i.IsSatisfied,
			&i.SatisfiedAt,
			&i.UserMessage,
			&i.WaitData,
			&i.InvocationCount,
		); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getDurableEventLogEntry = `-- name: GetDurableEventLogEntry :one
SELECT tenant_id, external_id, result_payload_external_id, child_task_external_id, inserted_at, id, durable_task_id, durable_task_inserted_at, kind, node_id, branch_id, idempotency_key, is_satisfied, satisfied_at, user_message, wait_data
FROM v1_durable_event_log_entry
WHERE durable_task_id = $1::BIGINT
  AND durable_task_inserted_at = $2::TIMESTAMPTZ
  AND branch_id = $3::BIGINT
  AND node_id = $4::BIGINT
`

type GetDurableEventLogEntryParams struct {
	Durabletaskid         int64              `json:"durabletaskid"`
	Durabletaskinsertedat pgtype.Timestamptz `json:"durabletaskinsertedat"`
	Branchid              int64              `json:"branchid"`
	Nodeid                int64              `json:"nodeid"`
}

func (q *Queries) GetDurableEventLogEntry(ctx context.Context, db DBTX, arg GetDurableEventLogEntryParams) (*V1DurableEventLogEntry, error) {
	row := db.QueryRow(ctx, getDurableEventLogEntry,
		arg.Durabletaskid,
		arg.Durabletaskinsertedat,
		arg.Branchid,
		arg.Nodeid,
	)
	var i V1DurableEventLogEntry
	err := row.Scan(
		&i.TenantID,
		&i.ExternalID,
		&i.ResultPayloadExternalID,
		&i.ChildTaskExternalID,
		&i.InsertedAt,
		&i.ID,
		&i.DurableTaskID,
		&i.DurableTaskInsertedAt,
		&i.Kind,
		&i.NodeID,
		&i.BranchID,
		&i.IdempotencyKey,
		&i.IsSatisfied,
		&i.SatisfiedAt,
		&i.UserMessage,
		&i.WaitData,
	)
	return &i, err
}

const getDurableTaskLogFiles = `-- name: GetDurableTaskLogFiles :many
WITH inputs AS (
    SELECT
        UNNEST($1::BIGINT[]) AS durable_task_id,
        UNNEST($2::TIMESTAMPTZ[]) AS durable_task_inserted_at,
        UNNEST($3::UUID[]) AS tenant_id
)

SELECT tenant_id, durable_task_id, durable_task_inserted_at, latest_invocation_count, latest_inserted_at, latest_node_id, latest_branch_id
FROM v1_durable_event_log_file lf
WHERE (lf.durable_task_id, lf.durable_task_inserted_at, lf.tenant_id) IN (
    SELECT durable_task_id, durable_task_inserted_at, tenant_id
    FROM inputs
)
`

type GetDurableTaskLogFilesParams struct {
	Durabletaskids         []int64              `json:"durabletaskids"`
	Durabletaskinsertedats []pgtype.Timestamptz `json:"durabletaskinsertedats"`
	Tenantids              []uuid.UUID          `json:"tenantids"`
}

func (q *Queries) GetDurableTaskLogFiles(ctx context.Context, db DBTX, arg GetDurableTaskLogFilesParams) ([]*V1DurableEventLogFile, error) {
	rows, err := db.Query(ctx, getDurableTaskLogFiles, arg.Durabletaskids, arg.Durabletaskinsertedats, arg.Tenantids)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*V1DurableEventLogFile
	for rows.Next() {
		var i V1DurableEventLogFile
		if err := rows.Scan(
			&i.TenantID,
			&i.DurableTaskID,
			&i.DurableTaskInsertedAt,
			&i.LatestInvocationCount,
			&i.LatestInsertedAt,
			&i.LatestNodeID,
			&i.LatestBranchID,
		); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const incrementLogFileInvocationCounts = `-- name: IncrementLogFileInvocationCounts :many
WITH inputs AS (
    SELECT
        UNNEST($1::BIGINT[]) AS durable_task_id,
        UNNEST($2::TIMESTAMPTZ[]) AS durable_task_inserted_at,
        UNNEST($3::UUID[]) AS tenant_id
)

INSERT INTO v1_durable_event_log_file (
    tenant_id,
    durable_task_id,
    durable_task_inserted_at,
    latest_invocation_count,
    latest_inserted_at,
    latest_node_id,
    latest_branch_id
)
SELECT
    tenant_id,
    durable_task_id,
    durable_task_inserted_at,
    1,
    NOW(),
    0,
    1
FROM inputs
ON CONFLICT (durable_task_id, durable_task_inserted_at) DO UPDATE
SET
    latest_invocation_count = v1_durable_event_log_file.latest_invocation_count + 1,
    latest_node_id = 0
RETURNING v1_durable_event_log_file.tenant_id, v1_durable_event_log_file.durable_task_id, v1_durable_event_log_file.durable_task_inserted_at, v1_durable_event_log_file.latest_invocation_count, v1_durable_event_log_file.latest_inserted_at, v1_durable_event_log_file.latest_node_id, v1_durable_event_log_file.latest_branch_id
`

type IncrementLogFileInvocationCountsParams struct {
	Durabletaskids         []int64              `json:"durabletaskids"`
	Durabletaskinsertedats []pgtype.Timestamptz `json:"durabletaskinsertedats"`
	Tenantids              []uuid.UUID          `json:"tenantids"`
}

func (q *Queries) IncrementLogFileInvocationCounts(ctx context.Context, db DBTX, arg IncrementLogFileInvocationCountsParams) ([]*V1DurableEventLogFile, error) {
	rows, err := db.Query(ctx, incrementLogFileInvocationCounts, arg.Durabletaskids, arg.Durabletaskinsertedats, arg.Tenantids)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*V1DurableEventLogFile
	for rows.Next() {
		var i V1DurableEventLogFile
		if err := rows.Scan(
			&i.TenantID,
			&i.DurableTaskID,
			&i.DurableTaskInsertedAt,
			&i.LatestInvocationCount,
			&i.LatestInsertedAt,
			&i.LatestNodeID,
			&i.LatestBranchID,
		); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listDurableEventLogBranchPoints = `-- name: ListDurableEventLogBranchPoints :many
SELECT tenant_id, id, inserted_at, durable_task_id, durable_task_inserted_at, first_node_id_in_new_branch, parent_branch_id, next_branch_id
FROM v1_durable_event_log_branch_point
WHERE
    durable_task_id = $1::BIGINT
    AND durable_task_inserted_at = $2::TIMESTAMPTZ
    AND tenant_id = $3::UUID
ORDER BY id ASC
`

type ListDurableEventLogBranchPointsParams struct {
	Durabletaskid         int64              `json:"durabletaskid"`
	Durabletaskinsertedat pgtype.Timestamptz `json:"durabletaskinsertedat"`
	Tenantid              uuid.UUID          `json:"tenantid"`
}

func (q *Queries) ListDurableEventLogBranchPoints(ctx context.Context, db DBTX, arg ListDurableEventLogBranchPointsParams) ([]*V1DurableEventLogBranchPoint, error) {
	rows, err := db.Query(ctx, listDurableEventLogBranchPoints, arg.Durabletaskid, arg.Durabletaskinsertedat, arg.Tenantid)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*V1DurableEventLogBranchPoint
	for rows.Next() {
		var i V1DurableEventLogBranchPoint
		if err := rows.Scan(
			&i.TenantID,
			&i.ID,
			&i.InsertedAt,
			&i.DurableTaskID,
			&i.DurableTaskInsertedAt,
			&i.FirstNodeIDInNewBranch,
			&i.ParentBranchID,
			&i.NextBranchID,
		); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listDurableEventLogForTask = `-- name: ListDurableEventLogForTask :many
SELECT e.tenant_id, e.external_id, e.result_payload_external_id, e.child_task_external_id, e.inserted_at, e.id, e.durable_task_id, e.durable_task_inserted_at, e.kind, e.node_id, e.branch_id, e.idempotency_key, e.is_satisfied, e.satisfied_at, e.user_message, e.wait_data, t.external_id AS durable_task_external_id, t.display_name AS durable_task_display_name
FROM v1_durable_event_log_entry e
JOIN v1_task t ON (t.id, t.inserted_at) = (e.durable_task_id, e.durable_task_inserted_at)
WHERE e.durable_task_id = $1::BIGINT
  AND e.durable_task_inserted_at = $2::TIMESTAMPTZ
  AND e.tenant_id = $3::UUID
ORDER BY e.branch_id ASC, e.node_id ASC
OFFSET $4::BIGINT
LIMIT $5::BIGINT
`

type ListDurableEventLogForTaskParams struct {
	Durabletaskid         int64              `json:"durabletaskid"`
	Durabletaskinsertedat pgtype.Timestamptz `json:"durabletaskinsertedat"`
	Tenantid              uuid.UUID          `json:"tenantid"`
	Eventlogoffset        int64              `json:"eventlogoffset"`
	Eventloglimit         int64              `json:"eventloglimit"`
}

type ListDurableEventLogForTaskRow struct {
	TenantID                uuid.UUID             `json:"tenant_id"`
	ExternalID              uuid.UUID             `json:"external_id"`
	ResultPayloadExternalID uuid.UUID             `json:"result_payload_external_id"`
	ChildTaskExternalID     *uuid.UUID            `json:"child_task_external_id"`
	InsertedAt              pgtype.Timestamptz    `json:"inserted_at"`
	ID                      int64                 `json:"id"`
	DurableTaskID           int64                 `json:"durable_task_id"`
	DurableTaskInsertedAt   pgtype.Timestamptz    `json:"durable_task_inserted_at"`
	Kind                    V1DurableEventLogKind `json:"kind"`
	NodeID                  int64                 `json:"node_id"`
	BranchID                int64                 `json:"branch_id"`
	IdempotencyKey          []byte                `json:"idempotency_key"`
	IsSatisfied             bool                  `json:"is_satisfied"`
	SatisfiedAt             pgtype.Timestamptz    `json:"satisfied_at"`
	UserMessage             pgtype.Text           `json:"user_message"`
	WaitData                []byte                `json:"wait_data"`
	DurableTaskExternalID   uuid.UUID             `json:"durable_task_external_id"`
	DurableTaskDisplayName  string                `json:"durable_task_display_name"`
}

func (q *Queries) ListDurableEventLogForTask(ctx context.Context, db DBTX, arg ListDurableEventLogForTaskParams) ([]*ListDurableEventLogForTaskRow, error) {
	rows, err := db.Query(ctx, listDurableEventLogForTask,
		arg.Durabletaskid,
		arg.Durabletaskinsertedat,
		arg.Tenantid,
		arg.Eventlogoffset,
		arg.Eventloglimit,
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*ListDurableEventLogForTaskRow
	for rows.Next() {
		var i ListDurableEventLogForTaskRow
		if err := rows.Scan(
			&i.TenantID,
			&i.ExternalID,
			&i.ResultPayloadExternalID,
			&i.ChildTaskExternalID,
			&i.InsertedAt,
			&i.ID,
			&i.DurableTaskID,
			&i.DurableTaskInsertedAt,
			&i.Kind,
			&i.NodeID,
			&i.BranchID,
			&i.IdempotencyKey,
			&i.IsSatisfied,
			&i.SatisfiedAt,
			&i.UserMessage,
			&i.WaitData,
			&i.DurableTaskExternalID,
			&i.DurableTaskDisplayName,
		); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listSatisfiedEntries = `-- name: ListSatisfiedEntries :many
WITH inputs AS (
    SELECT
        UNNEST($1::UUID[]) AS external_id,
        UNNEST($2::BIGINT[]) AS node_id,
        UNNEST($3::BIGINT[]) AS branch_id
), tasks_with_nodes AS (
    SELECT t.id, t.inserted_at, t.tenant_id, t.queue, t.action_id, t.step_id, t.step_readable_id, t.workflow_id, t.workflow_version_id, t.workflow_run_id, t.schedule_timeout, t.step_timeout, t.priority, t.sticky, t.desired_worker_id, t.external_id, t.display_name, t.input, t.retry_count, t.internal_retry_count, t.app_retry_count, t.step_index, t.additional_metadata, t.dag_id, t.dag_inserted_at, t.parent_task_external_id, t.parent_task_id, t.parent_task_inserted_at, t.child_index, t.child_key, t.initial_state, t.initial_state_reason, t.concurrency_parent_strategy_ids, t.concurrency_strategy_ids, t.concurrency_keys, t.retry_backoff_factor, t.retry_max_backoff, t.is_durable, t.desired_worker_label, t.triggering_event_external_id, t.triggering_event_key, i.node_id AS requested_node_id, i.branch_id AS requested_branch_id
    FROM inputs i
    JOIN v1_lookup_table lt ON lt.external_id = i.external_id
    JOIN v1_task t ON (t.id, t.inserted_at) = (lt.task_id, lt.inserted_at)
)

SELECT
    e.tenant_id, e.external_id, e.result_payload_external_id, e.child_task_external_id, e.inserted_at, e.id, e.durable_task_id, e.durable_task_inserted_at, e.kind, e.node_id, e.branch_id, e.idempotency_key, e.is_satisfied, e.satisfied_at, e.user_message, e.wait_data,
    twn.external_id AS task_external_id,
    lf.latest_invocation_count AS invocation_count
FROM v1_durable_event_log_entry e
JOIN tasks_with_nodes twn ON (twn.id, twn.inserted_at) = (e.durable_task_id, e.durable_task_inserted_at)
JOIN v1_durable_event_log_file lf ON (lf.durable_task_id, lf.durable_task_inserted_at) = (e.durable_task_id, e.durable_task_inserted_at)
WHERE
    e.branch_id = twn.requested_branch_id
    AND e.node_id = twn.requested_node_id
    AND e.is_satisfied
`

type ListSatisfiedEntriesParams struct {
	Taskexternalids []uuid.UUID `json:"taskexternalids"`
	Nodeids         []int64     `json:"nodeids"`
	Branchids       []int64     `json:"branchids"`
}

type ListSatisfiedEntriesRow struct {
	TenantID                uuid.UUID             `json:"tenant_id"`
	ExternalID              uuid.UUID             `json:"external_id"`
	ResultPayloadExternalID uuid.UUID             `json:"result_payload_external_id"`
	ChildTaskExternalID     *uuid.UUID            `json:"child_task_external_id"`
	InsertedAt              pgtype.Timestamptz    `json:"inserted_at"`
	ID                      int64                 `json:"id"`
	DurableTaskID           int64                 `json:"durable_task_id"`
	DurableTaskInsertedAt   pgtype.Timestamptz    `json:"durable_task_inserted_at"`
	Kind                    V1DurableEventLogKind `json:"kind"`
	NodeID                  int64                 `json:"node_id"`
	BranchID                int64                 `json:"branch_id"`
	IdempotencyKey          []byte                `json:"idempotency_key"`
	IsSatisfied             bool                  `json:"is_satisfied"`
	SatisfiedAt             pgtype.Timestamptz    `json:"satisfied_at"`
	UserMessage             pgtype.Text           `json:"user_message"`
	WaitData                []byte                `json:"wait_data"`
	TaskExternalID          uuid.UUID             `json:"task_external_id"`
	InvocationCount         int32                 `json:"invocation_count"`
}

func (q *Queries) ListSatisfiedEntries(ctx context.Context, db DBTX, arg ListSatisfiedEntriesParams) ([]*ListSatisfiedEntriesRow, error) {
	rows, err := db.Query(ctx, listSatisfiedEntries, arg.Taskexternalids, arg.Nodeids, arg.Branchids)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*ListSatisfiedEntriesRow
	for rows.Next() {
		var i ListSatisfiedEntriesRow
		if err := rows.Scan(
			&i.TenantID,
			&i.ExternalID,
			&i.ResultPayloadExternalID,
			&i.ChildTaskExternalID,
			&i.InsertedAt,
			&i.ID,
			&i.DurableTaskID,
			&i.DurableTaskInsertedAt,
			&i.Kind,
			&i.NodeID,
			&i.BranchID,
			&i.IdempotencyKey,
			&i.IsSatisfied,
			&i.SatisfiedAt,
			&i.UserMessage,
			&i.WaitData,
			&i.TaskExternalID,
			&i.InvocationCount,
		); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const markDurableEventLogEntrySatisfied = `-- name: MarkDurableEventLogEntrySatisfied :one
UPDATE v1_durable_event_log_entry
SET
    is_satisfied = true,
    satisfied_at = COALESCE(satisfied_at, NOW())
WHERE durable_task_id = $1::BIGINT
  AND durable_task_inserted_at = $2::TIMESTAMPTZ
  AND branch_id = $3::BIGINT
  AND node_id = $4::BIGINT
RETURNING tenant_id, external_id, result_payload_external_id, child_task_external_id, inserted_at, id, durable_task_id, durable_task_inserted_at, kind, node_id, branch_id, idempotency_key, is_satisfied, satisfied_at, user_message, wait_data
`

type MarkDurableEventLogEntrySatisfiedParams struct {
	Durabletaskid         int64              `json:"durabletaskid"`
	Durabletaskinsertedat pgtype.Timestamptz `json:"durabletaskinsertedat"`
	Branchid              int64              `json:"branchid"`
	Nodeid                int64              `json:"nodeid"`
}

func (q *Queries) MarkDurableEventLogEntrySatisfied(ctx context.Context, db DBTX, arg MarkDurableEventLogEntrySatisfiedParams) (*V1DurableEventLogEntry, error) {
	row := db.QueryRow(ctx, markDurableEventLogEntrySatisfied,
		arg.Durabletaskid,
		arg.Durabletaskinsertedat,
		arg.Branchid,
		arg.Nodeid,
	)
	var i V1DurableEventLogEntry
	err := row.Scan(
		&i.TenantID,
		&i.ExternalID,
		&i.ResultPayloadExternalID,
		&i.ChildTaskExternalID,
		&i.InsertedAt,
		&i.ID,
		&i.DurableTaskID,
		&i.DurableTaskInsertedAt,
		&i.Kind,
		&i.NodeID,
		&i.BranchID,
		&i.IdempotencyKey,
		&i.IsSatisfied,
		&i.SatisfiedAt,
		&i.UserMessage,
		&i.WaitData,
	)
	return &i, err
}

const updateDurableEventLogEntriesSatisfied = `-- name: UpdateDurableEventLogEntriesSatisfied :many
WITH inputs AS (
    SELECT
        UNNEST($1::BIGINT[]) AS durable_task_id,
        UNNEST($2::TIMESTAMPTZ[]) AS durable_task_inserted_at,
        UNNEST($3::BIGINT[]) AS node_id,
        UNNEST($4::BIGINT[]) AS branch_id
), updated AS (
    UPDATE v1_durable_event_log_entry
    SET
        is_satisfied = true,
        satisfied_at = COALESCE(satisfied_at, NOW())
    FROM inputs
    WHERE v1_durable_event_log_entry.durable_task_id = inputs.durable_task_id
      AND v1_durable_event_log_entry.durable_task_inserted_at = inputs.durable_task_inserted_at
      AND v1_durable_event_log_entry.node_id = inputs.node_id
      AND v1_durable_event_log_entry.branch_id = inputs.branch_id
    RETURNING v1_durable_event_log_entry.tenant_id, v1_durable_event_log_entry.external_id, v1_durable_event_log_entry.result_payload_external_id, v1_durable_event_log_entry.child_task_external_id, v1_durable_event_log_entry.inserted_at, v1_durable_event_log_entry.id, v1_durable_event_log_entry.durable_task_id, v1_durable_event_log_entry.durable_task_inserted_at, v1_durable_event_log_entry.kind, v1_durable_event_log_entry.node_id, v1_durable_event_log_entry.branch_id, v1_durable_event_log_entry.idempotency_key, v1_durable_event_log_entry.is_satisfied, v1_durable_event_log_entry.satisfied_at, v1_durable_event_log_entry.user_message, v1_durable_event_log_entry.wait_data
)

SELECT updated.tenant_id, updated.external_id, updated.result_payload_external_id, updated.child_task_external_id, updated.inserted_at, updated.id, updated.durable_task_id, updated.durable_task_inserted_at, updated.kind, updated.node_id, updated.branch_id, updated.idempotency_key, updated.is_satisfied, updated.satisfied_at, updated.user_message, updated.wait_data, lf.latest_invocation_count AS invocation_count
FROM updated
JOIN v1_durable_event_log_file lf ON (lf.durable_task_id, lf.durable_task_inserted_at) = (updated.durable_task_id, updated.durable_task_inserted_at)
`

type UpdateDurableEventLogEntriesSatisfiedParams struct {
	Durabletaskids         []int64              `json:"durabletaskids"`
	Durabletaskinsertedats []pgtype.Timestamptz `json:"durabletaskinsertedats"`
	Nodeids                []int64              `json:"nodeids"`
	Branchids              []int64              `json:"branchids"`
}

type UpdateDurableEventLogEntriesSatisfiedRow struct {
	TenantID                uuid.UUID             `json:"tenant_id"`
	ExternalID              uuid.UUID             `json:"external_id"`
	ResultPayloadExternalID uuid.UUID             `json:"result_payload_external_id"`
	ChildTaskExternalID     *uuid.UUID            `json:"child_task_external_id"`
	InsertedAt              pgtype.Timestamptz    `json:"inserted_at"`
	ID                      int64                 `json:"id"`
	DurableTaskID           int64                 `json:"durable_task_id"`
	DurableTaskInsertedAt   pgtype.Timestamptz    `json:"durable_task_inserted_at"`
	Kind                    V1DurableEventLogKind `json:"kind"`
	NodeID                  int64                 `json:"node_id"`
	BranchID                int64                 `json:"branch_id"`
	IdempotencyKey          []byte                `json:"idempotency_key"`
	IsSatisfied             bool                  `json:"is_satisfied"`
	SatisfiedAt             pgtype.Timestamptz    `json:"satisfied_at"`
	UserMessage             pgtype.Text           `json:"user_message"`
	WaitData                []byte                `json:"wait_data"`
	InvocationCount         int32                 `json:"invocation_count"`
}

func (q *Queries) UpdateDurableEventLogEntriesSatisfied(ctx context.Context, db DBTX, arg UpdateDurableEventLogEntriesSatisfiedParams) ([]*UpdateDurableEventLogEntriesSatisfiedRow, error) {
	rows, err := db.Query(ctx, updateDurableEventLogEntriesSatisfied,
		arg.Durabletaskids,
		arg.Durabletaskinsertedats,
		arg.Nodeids,
		arg.Branchids,
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*UpdateDurableEventLogEntriesSatisfiedRow
	for rows.Next() {
		var i UpdateDurableEventLogEntriesSatisfiedRow
		if err := rows.Scan(
			&i.TenantID,
			&i.ExternalID,
			&i.ResultPayloadExternalID,
			&i.ChildTaskExternalID,
			&i.InsertedAt,
			&i.ID,
			&i.DurableTaskID,
			&i.DurableTaskInsertedAt,
			&i.Kind,
			&i.NodeID,
			&i.BranchID,
			&i.IdempotencyKey,
			&i.IsSatisfied,
			&i.SatisfiedAt,
			&i.UserMessage,
			&i.WaitData,
			&i.InvocationCount,
		); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const updateLogFile = `-- name: UpdateLogFile :one
UPDATE v1_durable_event_log_file
SET
    -- important: need ` + "`" + `GREATEST` + "`" + ` here to avoid moving the ` + "`" + `latest_node_id` + "`" + ` backwards in the case of child spawning with
    -- a child_key set, which, if the child was cached, would not create a new log entry and thus not move the latest node forward
    latest_node_id = GREATEST(v1_durable_event_log_file.latest_node_id, COALESCE($1::BIGINT, v1_durable_event_log_file.latest_node_id)),
    latest_invocation_count = COALESCE($2::INTEGER, v1_durable_event_log_file.latest_invocation_count),
    latest_branch_id = COALESCE($3::BIGINT, v1_durable_event_log_file.latest_branch_id)
WHERE durable_task_id = $4::BIGINT
  AND durable_task_inserted_at = $5::TIMESTAMPTZ
RETURNING tenant_id, durable_task_id, durable_task_inserted_at, latest_invocation_count, latest_inserted_at, latest_node_id, latest_branch_id
`

type UpdateLogFileParams struct {
	NodeId                pgtype.Int8        `json:"nodeId"`
	InvocationCount       pgtype.Int4        `json:"invocationCount"`
	BranchId              pgtype.Int8        `json:"branchId"`
	Durabletaskid         int64              `json:"durabletaskid"`
	Durabletaskinsertedat pgtype.Timestamptz `json:"durabletaskinsertedat"`
}

func (q *Queries) UpdateLogFile(ctx context.Context, db DBTX, arg UpdateLogFileParams) (*V1DurableEventLogFile, error) {
	row := db.QueryRow(ctx, updateLogFile,
		arg.NodeId,
		arg.InvocationCount,
		arg.BranchId,
		arg.Durabletaskid,
		arg.Durabletaskinsertedat,
	)
	var i V1DurableEventLogFile
	err := row.Scan(
		&i.TenantID,
		&i.DurableTaskID,
		&i.DurableTaskInsertedAt,
		&i.LatestInvocationCount,
		&i.LatestInsertedAt,
		&i.LatestNodeID,
		&i.LatestBranchID,
	)
	return &i, err
}
