// 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 createTask = `-- name: CreateTask :one
INSERT INTO tasks (workflow_id, name, finished, result, error, created_at, updated_at)
VALUES ($1, $2, $3, $4, $5, $6, $7)
RETURNING workflow_id, name, finished, result, error, created_at, updated_at
`

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

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,
	)
	var i Task
	err := row.Scan(
		&i.WorkflowID,
		&i.Name,
		&i.Finished,
		&i.Result,
		&i.Error,
		&i.CreatedAt,
		&i.UpdatedAt,
	)
	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
`

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,
	)
	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
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,
	)
	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
FROM tasks
ORDER BY created_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,
		); 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
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,
		); 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 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
`

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