// Code generated by sqlc. DO NOT EDIT.
// versions:
//   sqlc v1.15.0
// source: workflows.sql

package db

import (
	"context"
	"database/sql"
	"time"

	"github.com/google/uuid"
)

const approveTask = `-- name: ApproveTask :one
UPDATE tasks
SET approved_at = $3,
    updated_at  = $3
WHERE workflow_id = $1
  AND name = $2
RETURNING workflow_id, name, finished, result, error, created_at, updated_at, approved_at, ready_for_approval, started, retry_count
`

type ApproveTaskParams struct {
	WorkflowID uuid.UUID
	Name       string
	ApprovedAt sql.NullTime
}

func (q *Queries) ApproveTask(ctx context.Context, arg ApproveTaskParams) (Task, error) {
	row := q.db.QueryRow(ctx, approveTask, arg.WorkflowID, arg.Name, arg.ApprovedAt)
	var i Task
	err := row.Scan(
		&i.WorkflowID,
		&i.Name,
		&i.Finished,
		&i.Result,
		&i.Error,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.ApprovedAt,
		&i.ReadyForApproval,
		&i.Started,
		&i.RetryCount,
	)
	return i, err
}

const clearWorkflowSchedule = `-- name: ClearWorkflowSchedule :many
UPDATE workflows
SET schedule_id = NULL
WHERE schedule_id = $1::int
RETURNING id
`

func (q *Queries) ClearWorkflowSchedule(ctx context.Context, dollar_1 int32) ([]uuid.UUID, error) {
	rows, err := q.db.Query(ctx, clearWorkflowSchedule, dollar_1)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []uuid.UUID
	for rows.Next() {
		var id uuid.UUID
		if err := rows.Scan(&id); err != nil {
			return nil, err
		}
		items = append(items, id)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const createSchedule = `-- name: CreateSchedule :one
INSERT INTO schedules (workflow_name, workflow_params, spec, once, interval_minutes, created_at, updated_at)
VALUES ($1, $2, $3, $4, $5, $6, $7)
RETURNING id, workflow_name, workflow_params, spec, once, interval_minutes, created_at, updated_at
`

type CreateScheduleParams struct {
	WorkflowName    string
	WorkflowParams  sql.NullString
	Spec            string
	Once            time.Time
	IntervalMinutes int32
	CreatedAt       time.Time
	UpdatedAt       time.Time
}

func (q *Queries) CreateSchedule(ctx context.Context, arg CreateScheduleParams) (Schedule, error) {
	row := q.db.QueryRow(ctx, createSchedule,
		arg.WorkflowName,
		arg.WorkflowParams,
		arg.Spec,
		arg.Once,
		arg.IntervalMinutes,
		arg.CreatedAt,
		arg.UpdatedAt,
	)
	var i Schedule
	err := row.Scan(
		&i.ID,
		&i.WorkflowName,
		&i.WorkflowParams,
		&i.Spec,
		&i.Once,
		&i.IntervalMinutes,
		&i.CreatedAt,
		&i.UpdatedAt,
	)
	return i, err
}

const createTask = `-- name: CreateTask :one
INSERT INTO tasks (workflow_id, name, finished, result, error, created_at, updated_at, approved_at,
                   ready_for_approval)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
RETURNING workflow_id, name, finished, result, error, created_at, updated_at, approved_at, ready_for_approval, started, retry_count
`

type CreateTaskParams struct {
	WorkflowID       uuid.UUID
	Name             string
	Finished         bool
	Result           sql.NullString
	Error            sql.NullString
	CreatedAt        time.Time
	UpdatedAt        time.Time
	ApprovedAt       sql.NullTime
	ReadyForApproval bool
}

func (q *Queries) CreateTask(ctx context.Context, arg CreateTaskParams) (Task, error) {
	row := q.db.QueryRow(ctx, createTask,
		arg.WorkflowID,
		arg.Name,
		arg.Finished,
		arg.Result,
		arg.Error,
		arg.CreatedAt,
		arg.UpdatedAt,
		arg.ApprovedAt,
		arg.ReadyForApproval,
	)
	var i Task
	err := row.Scan(
		&i.WorkflowID,
		&i.Name,
		&i.Finished,
		&i.Result,
		&i.Error,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.ApprovedAt,
		&i.ReadyForApproval,
		&i.Started,
		&i.RetryCount,
	)
	return i, err
}

const createTaskLog = `-- name: CreateTaskLog :one
INSERT INTO task_logs (workflow_id, task_name, body)
VALUES ($1, $2, $3)
RETURNING id, workflow_id, task_name, body, created_at, updated_at
`

type CreateTaskLogParams struct {
	WorkflowID uuid.UUID
	TaskName   string
	Body       string
}

func (q *Queries) CreateTaskLog(ctx context.Context, arg CreateTaskLogParams) (TaskLog, error) {
	row := q.db.QueryRow(ctx, createTaskLog, arg.WorkflowID, arg.TaskName, arg.Body)
	var i TaskLog
	err := row.Scan(
		&i.ID,
		&i.WorkflowID,
		&i.TaskName,
		&i.Body,
		&i.CreatedAt,
		&i.UpdatedAt,
	)
	return i, err
}

const createWorkflow = `-- name: CreateWorkflow :one
INSERT INTO workflows (id, params, name, schedule_id, created_at, updated_at)
VALUES ($1, $2, $3, $4, $5, $6)
RETURNING id, params, name, created_at, updated_at, finished, output, error, schedule_id
`

type CreateWorkflowParams struct {
	ID         uuid.UUID
	Params     sql.NullString
	Name       sql.NullString
	ScheduleID sql.NullInt32
	CreatedAt  time.Time
	UpdatedAt  time.Time
}

func (q *Queries) CreateWorkflow(ctx context.Context, arg CreateWorkflowParams) (Workflow, error) {
	row := q.db.QueryRow(ctx, createWorkflow,
		arg.ID,
		arg.Params,
		arg.Name,
		arg.ScheduleID,
		arg.CreatedAt,
		arg.UpdatedAt,
	)
	var i Workflow
	err := row.Scan(
		&i.ID,
		&i.Params,
		&i.Name,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Finished,
		&i.Output,
		&i.Error,
		&i.ScheduleID,
	)
	return i, err
}

const deleteSchedule = `-- name: DeleteSchedule :one
DELETE
FROM schedules
WHERE id = $1
RETURNING id, workflow_name, workflow_params, spec, once, interval_minutes, created_at, updated_at
`

func (q *Queries) DeleteSchedule(ctx context.Context, id int32) (Schedule, error) {
	row := q.db.QueryRow(ctx, deleteSchedule, id)
	var i Schedule
	err := row.Scan(
		&i.ID,
		&i.WorkflowName,
		&i.WorkflowParams,
		&i.Spec,
		&i.Once,
		&i.IntervalMinutes,
		&i.CreatedAt,
		&i.UpdatedAt,
	)
	return i, err
}

const resetTask = `-- name: ResetTask :one
UPDATE tasks
SET finished    = FALSE,
    started     = FALSE,
    approved_at = DEFAULT,
    result      = DEFAULT,
    error       = DEFAULT,
    updated_at  = $3
WHERE workflow_id = $1
  AND name = $2
RETURNING workflow_id, name, finished, result, error, created_at, updated_at, approved_at, ready_for_approval, started, retry_count
`

type ResetTaskParams struct {
	WorkflowID uuid.UUID
	Name       string
	UpdatedAt  time.Time
}

func (q *Queries) ResetTask(ctx context.Context, arg ResetTaskParams) (Task, error) {
	row := q.db.QueryRow(ctx, resetTask, arg.WorkflowID, arg.Name, arg.UpdatedAt)
	var i Task
	err := row.Scan(
		&i.WorkflowID,
		&i.Name,
		&i.Finished,
		&i.Result,
		&i.Error,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.ApprovedAt,
		&i.ReadyForApproval,
		&i.Started,
		&i.RetryCount,
	)
	return i, err
}

const resetWorkflow = `-- name: ResetWorkflow :one
UPDATE workflows
SET finished   = FALSE,
    output     = DEFAULT,
    error      = DEFAULT,
    updated_at = $2
WHERE id = $1
RETURNING id, params, name, created_at, updated_at, finished, output, error, schedule_id
`

type ResetWorkflowParams struct {
	ID        uuid.UUID
	UpdatedAt time.Time
}

func (q *Queries) ResetWorkflow(ctx context.Context, arg ResetWorkflowParams) (Workflow, error) {
	row := q.db.QueryRow(ctx, resetWorkflow, arg.ID, arg.UpdatedAt)
	var i Workflow
	err := row.Scan(
		&i.ID,
		&i.Params,
		&i.Name,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Finished,
		&i.Output,
		&i.Error,
		&i.ScheduleID,
	)
	return i, err
}

const schedules = `-- name: Schedules :many
SELECT id, workflow_name, workflow_params, spec, once, interval_minutes, created_at, updated_at
FROM schedules
ORDER BY id
`

func (q *Queries) Schedules(ctx context.Context) ([]Schedule, error) {
	rows, err := q.db.Query(ctx, schedules)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []Schedule
	for rows.Next() {
		var i Schedule
		if err := rows.Scan(
			&i.ID,
			&i.WorkflowName,
			&i.WorkflowParams,
			&i.Spec,
			&i.Once,
			&i.IntervalMinutes,
			&i.CreatedAt,
			&i.UpdatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const schedulesLastRun = `-- name: SchedulesLastRun :many
WITH last_scheduled_run AS (
    SELECT DISTINCT ON (schedule_id) schedule_id, id, created_at, workflows.error, finished
    FROM workflows
    ORDER BY schedule_id, workflows.created_at DESC
)
SELECT schedules.id,
       last_scheduled_run.id AS workflow_id,
       last_scheduled_run.created_at AS workflow_created_at,
       last_scheduled_run.error AS workflow_error,
       last_scheduled_run.finished AS workflow_finished
FROM schedules
LEFT OUTER JOIN last_scheduled_run ON last_scheduled_run.schedule_id = schedules.id
`

type SchedulesLastRunRow struct {
	ID                int32
	WorkflowID        uuid.UUID
	WorkflowCreatedAt sql.NullTime
	WorkflowError     sql.NullString
	WorkflowFinished  sql.NullBool
}

func (q *Queries) SchedulesLastRun(ctx context.Context) ([]SchedulesLastRunRow, error) {
	rows, err := q.db.Query(ctx, schedulesLastRun)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []SchedulesLastRunRow
	for rows.Next() {
		var i SchedulesLastRunRow
		if err := rows.Scan(
			&i.ID,
			&i.WorkflowID,
			&i.WorkflowCreatedAt,
			&i.WorkflowError,
			&i.WorkflowFinished,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const task = `-- name: Task :one
SELECT tasks.workflow_id, tasks.name, tasks.finished, tasks.result, tasks.error, tasks.created_at, tasks.updated_at, tasks.approved_at, tasks.ready_for_approval, tasks.started, tasks.retry_count
FROM tasks
WHERE workflow_id = $1
  AND name = $2
LIMIT 1
`

type TaskParams struct {
	WorkflowID uuid.UUID
	Name       string
}

func (q *Queries) Task(ctx context.Context, arg TaskParams) (Task, error) {
	row := q.db.QueryRow(ctx, task, arg.WorkflowID, arg.Name)
	var i Task
	err := row.Scan(
		&i.WorkflowID,
		&i.Name,
		&i.Finished,
		&i.Result,
		&i.Error,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.ApprovedAt,
		&i.ReadyForApproval,
		&i.Started,
		&i.RetryCount,
	)
	return i, err
}

const taskLogs = `-- name: TaskLogs :many
SELECT task_logs.id, task_logs.workflow_id, task_logs.task_name, task_logs.body, task_logs.created_at, task_logs.updated_at
FROM task_logs
ORDER BY created_at
`

func (q *Queries) TaskLogs(ctx context.Context) ([]TaskLog, error) {
	rows, err := q.db.Query(ctx, taskLogs)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []TaskLog
	for rows.Next() {
		var i TaskLog
		if err := rows.Scan(
			&i.ID,
			&i.WorkflowID,
			&i.TaskName,
			&i.Body,
			&i.CreatedAt,
			&i.UpdatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const taskLogsForTask = `-- name: TaskLogsForTask :many
SELECT task_logs.id, task_logs.workflow_id, task_logs.task_name, task_logs.body, task_logs.created_at, task_logs.updated_at
FROM task_logs
WHERE workflow_id = $1
  AND task_name = $2
ORDER BY created_at
`

type TaskLogsForTaskParams struct {
	WorkflowID uuid.UUID
	TaskName   string
}

func (q *Queries) TaskLogsForTask(ctx context.Context, arg TaskLogsForTaskParams) ([]TaskLog, error) {
	rows, err := q.db.Query(ctx, taskLogsForTask, arg.WorkflowID, arg.TaskName)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []TaskLog
	for rows.Next() {
		var i TaskLog
		if err := rows.Scan(
			&i.ID,
			&i.WorkflowID,
			&i.TaskName,
			&i.Body,
			&i.CreatedAt,
			&i.UpdatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const taskLogsForWorkflow = `-- name: TaskLogsForWorkflow :many
SELECT task_logs.id, task_logs.workflow_id, task_logs.task_name, task_logs.body, task_logs.created_at, task_logs.updated_at
FROM task_logs
WHERE workflow_id = $1
ORDER BY created_at
`

func (q *Queries) TaskLogsForWorkflow(ctx context.Context, workflowID uuid.UUID) ([]TaskLog, error) {
	rows, err := q.db.Query(ctx, taskLogsForWorkflow, workflowID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []TaskLog
	for rows.Next() {
		var i TaskLog
		if err := rows.Scan(
			&i.ID,
			&i.WorkflowID,
			&i.TaskName,
			&i.Body,
			&i.CreatedAt,
			&i.UpdatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const tasks = `-- name: Tasks :many
WITH most_recent_logs AS (
    SELECT workflow_id, task_name, MAX(updated_at) AS updated_at
    FROM task_logs
    GROUP BY workflow_id, task_name
)
SELECT tasks.workflow_id, tasks.name, tasks.finished, tasks.result, tasks.error, tasks.created_at, tasks.updated_at, tasks.approved_at, tasks.ready_for_approval, tasks.started, tasks.retry_count,
       GREATEST(most_recent_logs.updated_at, tasks.updated_at)::timestamptz AS most_recent_update
FROM tasks
LEFT JOIN most_recent_logs ON tasks.workflow_id = most_recent_logs.workflow_id AND
                              tasks.name = most_recent_logs.task_name
ORDER BY most_recent_update DESC
`

type TasksRow struct {
	WorkflowID       uuid.UUID
	Name             string
	Finished         bool
	Result           sql.NullString
	Error            sql.NullString
	CreatedAt        time.Time
	UpdatedAt        time.Time
	ApprovedAt       sql.NullTime
	ReadyForApproval bool
	Started          bool
	RetryCount       int32
	MostRecentUpdate time.Time
}

func (q *Queries) Tasks(ctx context.Context) ([]TasksRow, error) {
	rows, err := q.db.Query(ctx, tasks)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []TasksRow
	for rows.Next() {
		var i TasksRow
		if err := rows.Scan(
			&i.WorkflowID,
			&i.Name,
			&i.Finished,
			&i.Result,
			&i.Error,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.ApprovedAt,
			&i.ReadyForApproval,
			&i.Started,
			&i.RetryCount,
			&i.MostRecentUpdate,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const tasksForWorkflow = `-- name: TasksForWorkflow :many
SELECT tasks.workflow_id, tasks.name, tasks.finished, tasks.result, tasks.error, tasks.created_at, tasks.updated_at, tasks.approved_at, tasks.ready_for_approval, tasks.started, tasks.retry_count
FROM tasks
WHERE workflow_id = $1
ORDER BY created_at
`

func (q *Queries) TasksForWorkflow(ctx context.Context, workflowID uuid.UUID) ([]Task, error) {
	rows, err := q.db.Query(ctx, tasksForWorkflow, workflowID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []Task
	for rows.Next() {
		var i Task
		if err := rows.Scan(
			&i.WorkflowID,
			&i.Name,
			&i.Finished,
			&i.Result,
			&i.Error,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.ApprovedAt,
			&i.ReadyForApproval,
			&i.Started,
			&i.RetryCount,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const tasksForWorkflowSorted = `-- name: TasksForWorkflowSorted :many
WITH most_recent_logs AS (
    SELECT workflow_id, task_name, MAX(updated_at) AS updated_at
    FROM task_logs
    GROUP BY workflow_id, task_name
)
SELECT tasks.workflow_id, tasks.name, tasks.finished, tasks.result, tasks.error, tasks.created_at, tasks.updated_at, tasks.approved_at, tasks.ready_for_approval, tasks.started, tasks.retry_count,
       GREATEST(most_recent_logs.updated_at, tasks.updated_at)::timestamptz AS most_recent_update
FROM tasks
LEFT JOIN most_recent_logs ON tasks.workflow_id = most_recent_logs.workflow_id AND
                              tasks.name = most_recent_logs.task_name
WHERE tasks.workflow_id = $1
ORDER BY most_recent_update DESC
`

type TasksForWorkflowSortedRow struct {
	WorkflowID       uuid.UUID
	Name             string
	Finished         bool
	Result           sql.NullString
	Error            sql.NullString
	CreatedAt        time.Time
	UpdatedAt        time.Time
	ApprovedAt       sql.NullTime
	ReadyForApproval bool
	Started          bool
	RetryCount       int32
	MostRecentUpdate time.Time
}

func (q *Queries) TasksForWorkflowSorted(ctx context.Context, workflowID uuid.UUID) ([]TasksForWorkflowSortedRow, error) {
	rows, err := q.db.Query(ctx, tasksForWorkflowSorted, workflowID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []TasksForWorkflowSortedRow
	for rows.Next() {
		var i TasksForWorkflowSortedRow
		if err := rows.Scan(
			&i.WorkflowID,
			&i.Name,
			&i.Finished,
			&i.Result,
			&i.Error,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.ApprovedAt,
			&i.ReadyForApproval,
			&i.Started,
			&i.RetryCount,
			&i.MostRecentUpdate,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const unfinishedWorkflows = `-- name: UnfinishedWorkflows :many
SELECT workflows.id, workflows.params, workflows.name, workflows.created_at, workflows.updated_at, workflows.finished, workflows.output, workflows.error, workflows.schedule_id
FROM workflows
WHERE workflows.finished = FALSE
`

func (q *Queries) UnfinishedWorkflows(ctx context.Context) ([]Workflow, error) {
	rows, err := q.db.Query(ctx, unfinishedWorkflows)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []Workflow
	for rows.Next() {
		var i Workflow
		if err := rows.Scan(
			&i.ID,
			&i.Params,
			&i.Name,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.Finished,
			&i.Output,
			&i.Error,
			&i.ScheduleID,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const updateTaskReadyForApproval = `-- name: UpdateTaskReadyForApproval :one
UPDATE tasks
SET ready_for_approval = $3
WHERE workflow_id = $1
  AND name = $2
RETURNING workflow_id, name, finished, result, error, created_at, updated_at, approved_at, ready_for_approval, started, retry_count
`

type UpdateTaskReadyForApprovalParams struct {
	WorkflowID       uuid.UUID
	Name             string
	ReadyForApproval bool
}

func (q *Queries) UpdateTaskReadyForApproval(ctx context.Context, arg UpdateTaskReadyForApprovalParams) (Task, error) {
	row := q.db.QueryRow(ctx, updateTaskReadyForApproval, arg.WorkflowID, arg.Name, arg.ReadyForApproval)
	var i Task
	err := row.Scan(
		&i.WorkflowID,
		&i.Name,
		&i.Finished,
		&i.Result,
		&i.Error,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.ApprovedAt,
		&i.ReadyForApproval,
		&i.Started,
		&i.RetryCount,
	)
	return i, err
}

const upsertTask = `-- name: UpsertTask :one
INSERT INTO tasks (workflow_id, name, started, finished, result, error, created_at, updated_at,
                   retry_count)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
ON CONFLICT (workflow_id, name) DO UPDATE
    SET workflow_id = excluded.workflow_id,
        name        = excluded.name,
        started     = excluded.started,
        finished    = excluded.finished,
        result      = excluded.result,
        error       = excluded.error,
        updated_at  = excluded.updated_at,
        retry_count = excluded.retry_count
RETURNING workflow_id, name, finished, result, error, created_at, updated_at, approved_at, ready_for_approval, started, retry_count
`

type UpsertTaskParams struct {
	WorkflowID uuid.UUID
	Name       string
	Started    bool
	Finished   bool
	Result     sql.NullString
	Error      sql.NullString
	CreatedAt  time.Time
	UpdatedAt  time.Time
	RetryCount int32
}

func (q *Queries) UpsertTask(ctx context.Context, arg UpsertTaskParams) (Task, error) {
	row := q.db.QueryRow(ctx, upsertTask,
		arg.WorkflowID,
		arg.Name,
		arg.Started,
		arg.Finished,
		arg.Result,
		arg.Error,
		arg.CreatedAt,
		arg.UpdatedAt,
		arg.RetryCount,
	)
	var i Task
	err := row.Scan(
		&i.WorkflowID,
		&i.Name,
		&i.Finished,
		&i.Result,
		&i.Error,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.ApprovedAt,
		&i.ReadyForApproval,
		&i.Started,
		&i.RetryCount,
	)
	return i, err
}

const workflow = `-- name: Workflow :one
SELECT id, params, name, created_at, updated_at, finished, output, error, schedule_id
FROM workflows
WHERE id = $1
`

func (q *Queries) Workflow(ctx context.Context, id uuid.UUID) (Workflow, error) {
	row := q.db.QueryRow(ctx, workflow, id)
	var i Workflow
	err := row.Scan(
		&i.ID,
		&i.Params,
		&i.Name,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Finished,
		&i.Output,
		&i.Error,
		&i.ScheduleID,
	)
	return i, err
}

const workflowCount = `-- name: WorkflowCount :one
SELECT COUNT(*)
FROM workflows
`

func (q *Queries) WorkflowCount(ctx context.Context) (int64, error) {
	row := q.db.QueryRow(ctx, workflowCount)
	var count int64
	err := row.Scan(&count)
	return count, err
}

const workflowFinished = `-- name: WorkflowFinished :one
UPDATE workflows
SET finished   = $2,
    output     = $3,
    error      = $4,
    updated_at = $5
WHERE workflows.id = $1
RETURNING id, params, name, created_at, updated_at, finished, output, error, schedule_id
`

type WorkflowFinishedParams struct {
	ID        uuid.UUID
	Finished  bool
	Output    string
	Error     string
	UpdatedAt time.Time
}

func (q *Queries) WorkflowFinished(ctx context.Context, arg WorkflowFinishedParams) (Workflow, error) {
	row := q.db.QueryRow(ctx, workflowFinished,
		arg.ID,
		arg.Finished,
		arg.Output,
		arg.Error,
		arg.UpdatedAt,
	)
	var i Workflow
	err := row.Scan(
		&i.ID,
		&i.Params,
		&i.Name,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Finished,
		&i.Output,
		&i.Error,
		&i.ScheduleID,
	)
	return i, err
}

const workflowNames = `-- name: WorkflowNames :many
SELECT DISTINCT name::text
FROM workflows
`

func (q *Queries) WorkflowNames(ctx context.Context) ([]string, error) {
	rows, err := q.db.Query(ctx, workflowNames)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []string
	for rows.Next() {
		var name string
		if err := rows.Scan(&name); err != nil {
			return nil, err
		}
		items = append(items, name)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const workflowSidebar = `-- name: WorkflowSidebar :many
SELECT name, COUNT(*)
FROM workflows
GROUP BY name
ORDER BY name
`

type WorkflowSidebarRow struct {
	Name  sql.NullString
	Count int64
}

func (q *Queries) WorkflowSidebar(ctx context.Context) ([]WorkflowSidebarRow, error) {
	rows, err := q.db.Query(ctx, workflowSidebar)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []WorkflowSidebarRow
	for rows.Next() {
		var i WorkflowSidebarRow
		if err := rows.Scan(&i.Name, &i.Count); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const workflows = `-- name: Workflows :many

SELECT id, params, name, created_at, updated_at, finished, output, error, schedule_id
FROM workflows
ORDER BY created_at DESC
`

// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
func (q *Queries) Workflows(ctx context.Context) ([]Workflow, error) {
	rows, err := q.db.Query(ctx, workflows)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []Workflow
	for rows.Next() {
		var i Workflow
		if err := rows.Scan(
			&i.ID,
			&i.Params,
			&i.Name,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.Finished,
			&i.Output,
			&i.Error,
			&i.ScheduleID,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const workflowsByName = `-- name: WorkflowsByName :many
SELECT id, params, name, created_at, updated_at, finished, output, error, schedule_id
FROM workflows
WHERE name = $1
ORDER BY created_at DESC
`

func (q *Queries) WorkflowsByName(ctx context.Context, name sql.NullString) ([]Workflow, error) {
	rows, err := q.db.Query(ctx, workflowsByName, name)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []Workflow
	for rows.Next() {
		var i Workflow
		if err := rows.Scan(
			&i.ID,
			&i.Params,
			&i.Name,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.Finished,
			&i.Output,
			&i.Error,
			&i.ScheduleID,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const workflowsByNames = `-- name: WorkflowsByNames :many
SELECT id, params, name, created_at, updated_at, finished, output, error, schedule_id
FROM workflows
WHERE name = ANY($1::text[])
ORDER BY created_at DESC
`

func (q *Queries) WorkflowsByNames(ctx context.Context, names []string) ([]Workflow, error) {
	rows, err := q.db.Query(ctx, workflowsByNames, names)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []Workflow
	for rows.Next() {
		var i Workflow
		if err := rows.Scan(
			&i.ID,
			&i.Params,
			&i.Name,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.Finished,
			&i.Output,
			&i.Error,
			&i.ScheduleID,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}
