// Code generated by sqlc. DO NOT EDIT.
// versions:
//   sqlc v1.13.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
`

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,
	)
	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
`

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,
	)
	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, created_at, updated_at)
VALUES ($1, $2, $3, $4, $5)
RETURNING id, params, name, created_at, updated_at, finished, output, error
`

type CreateWorkflowParams struct {
	ID        uuid.UUID
	Params    sql.NullString
	Name      sql.NullString
	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.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,
	)
	return i, err
}

const resetTask = `-- name: ResetTask :one
UPDATE tasks
SET finished   = FALSE,
    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
`

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,
	)
	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
`

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,
	)
	return i, err
}

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
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,
	)
	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 tasks = `-- name: Tasks :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
FROM tasks
ORDER BY updated_at
`

func (q *Queries) Tasks(ctx context.Context) ([]Task, error) {
	rows, err := q.db.Query(ctx, tasks)
	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,
		); 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
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,
		); 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
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,
		); 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
`

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,
	)
	return i, err
}

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

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

func (q *Queries) UpsertTask(ctx context.Context, arg UpsertTaskParams) (Task, error) {
	row := q.db.QueryRow(ctx, upsertTask,
		arg.WorkflowID,
		arg.Name,
		arg.Finished,
		arg.Result,
		arg.Error,
		arg.CreatedAt,
		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,
	)
	return i, err
}

const workflow = `-- name: Workflow :one
SELECT id, params, name, created_at, updated_at, finished, output, error
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,
	)
	return i, 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
`

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,
	)
	return i, err
}

const workflows = `-- name: Workflows :many

SELECT id, params, name, created_at, updated_at, finished, output, error
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,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}
