// 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 failUnfinishedTasks = `-- name: FailUnfinishedTasks :exec
UPDATE tasks
    SET finished = TRUE,
    started      = TRUE,
    error        = 'task interrupted before completion',
    updated_at   = $2
WHERE workflow_id = $1 and started and not finished
`

type FailUnfinishedTasksParams struct {
	WorkflowID uuid.UUID
	UpdatedAt  time.Time
}

func (q *Queries) FailUnfinishedTasks(ctx context.Context, arg FailUnfinishedTasksParams) error {
	_, err := q.db.Exec(ctx, failUnfinishedTasks, arg.WorkflowID, arg.UpdatedAt)
	return 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
}
