// 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 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 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
FROM workflows
`

func (q *Queries) WorkflowNames(ctx context.Context) ([]sql.NullString, error) {
	rows, err := q.db.Query(ctx, workflowNames)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []sql.NullString
	for rows.Next() {
		var name sql.NullString
		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
}
