// Code generated by sqlc. DO NOT EDIT.
// versions:
//   sqlc v1.13.0

package database

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

	"github.com/coder/coder/coderd/database/dbtypes"
	"github.com/google/uuid"
	"github.com/lib/pq"
	"github.com/tabbed/pqtype"
)

const deleteAPIKeyByID = `-- name: DeleteAPIKeyByID :exec
DELETE
FROM
	api_keys
WHERE
	id = $1
`

func (q *sqlQuerier) DeleteAPIKeyByID(ctx context.Context, id string) error {
	_, err := q.db.ExecContext(ctx, deleteAPIKeyByID, id)
	return err
}

const getAPIKeyByID = `-- name: GetAPIKeyByID :one
SELECT
	id, hashed_secret, user_id, last_used, expires_at, created_at, updated_at, login_type, lifetime_seconds, ip_address
FROM
	api_keys
WHERE
	id = $1
LIMIT
	1
`

func (q *sqlQuerier) GetAPIKeyByID(ctx context.Context, id string) (APIKey, error) {
	row := q.db.QueryRowContext(ctx, getAPIKeyByID, id)
	var i APIKey
	err := row.Scan(
		&i.ID,
		&i.HashedSecret,
		&i.UserID,
		&i.LastUsed,
		&i.ExpiresAt,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.LoginType,
		&i.LifetimeSeconds,
		&i.IPAddress,
	)
	return i, err
}

const getAPIKeysLastUsedAfter = `-- name: GetAPIKeysLastUsedAfter :many
SELECT id, hashed_secret, user_id, last_used, expires_at, created_at, updated_at, login_type, lifetime_seconds, ip_address FROM api_keys WHERE last_used > $1
`

func (q *sqlQuerier) GetAPIKeysLastUsedAfter(ctx context.Context, lastUsed time.Time) ([]APIKey, error) {
	rows, err := q.db.QueryContext(ctx, getAPIKeysLastUsedAfter, lastUsed)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []APIKey
	for rows.Next() {
		var i APIKey
		if err := rows.Scan(
			&i.ID,
			&i.HashedSecret,
			&i.UserID,
			&i.LastUsed,
			&i.ExpiresAt,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.LoginType,
			&i.LifetimeSeconds,
			&i.IPAddress,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const insertAPIKey = `-- name: InsertAPIKey :one
INSERT INTO
	api_keys (
		id,
		lifetime_seconds,
		hashed_secret,
		ip_address,
		user_id,
		last_used,
		expires_at,
		created_at,
		updated_at,
		login_type
	)
VALUES
	($1,
	 -- If the lifetime is set to 0, default to 24hrs
	 CASE $2::bigint
	     WHEN 0 THEN 86400
		 ELSE $2::bigint
	 END
	 , $3, $4, $5, $6, $7, $8, $9, $10) RETURNING id, hashed_secret, user_id, last_used, expires_at, created_at, updated_at, login_type, lifetime_seconds, ip_address
`

type InsertAPIKeyParams struct {
	ID              string      `db:"id" json:"id"`
	LifetimeSeconds int64       `db:"lifetime_seconds" json:"lifetime_seconds"`
	HashedSecret    []byte      `db:"hashed_secret" json:"hashed_secret"`
	IPAddress       pqtype.Inet `db:"ip_address" json:"ip_address"`
	UserID          uuid.UUID   `db:"user_id" json:"user_id"`
	LastUsed        time.Time   `db:"last_used" json:"last_used"`
	ExpiresAt       time.Time   `db:"expires_at" json:"expires_at"`
	CreatedAt       time.Time   `db:"created_at" json:"created_at"`
	UpdatedAt       time.Time   `db:"updated_at" json:"updated_at"`
	LoginType       LoginType   `db:"login_type" json:"login_type"`
}

func (q *sqlQuerier) InsertAPIKey(ctx context.Context, arg InsertAPIKeyParams) (APIKey, error) {
	row := q.db.QueryRowContext(ctx, insertAPIKey,
		arg.ID,
		arg.LifetimeSeconds,
		arg.HashedSecret,
		arg.IPAddress,
		arg.UserID,
		arg.LastUsed,
		arg.ExpiresAt,
		arg.CreatedAt,
		arg.UpdatedAt,
		arg.LoginType,
	)
	var i APIKey
	err := row.Scan(
		&i.ID,
		&i.HashedSecret,
		&i.UserID,
		&i.LastUsed,
		&i.ExpiresAt,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.LoginType,
		&i.LifetimeSeconds,
		&i.IPAddress,
	)
	return i, err
}

const updateAPIKeyByID = `-- name: UpdateAPIKeyByID :exec
UPDATE
	api_keys
SET
	last_used = $2,
	expires_at = $3,
	ip_address = $4
WHERE
	id = $1
`

type UpdateAPIKeyByIDParams struct {
	ID        string      `db:"id" json:"id"`
	LastUsed  time.Time   `db:"last_used" json:"last_used"`
	ExpiresAt time.Time   `db:"expires_at" json:"expires_at"`
	IPAddress pqtype.Inet `db:"ip_address" json:"ip_address"`
}

func (q *sqlQuerier) UpdateAPIKeyByID(ctx context.Context, arg UpdateAPIKeyByIDParams) error {
	_, err := q.db.ExecContext(ctx, updateAPIKeyByID,
		arg.ID,
		arg.LastUsed,
		arg.ExpiresAt,
		arg.IPAddress,
	)
	return err
}

const getAuditLogsBefore = `-- name: GetAuditLogsBefore :many
SELECT
	id, time, user_id, organization_id, ip, user_agent, resource_type, resource_id, resource_target, action, diff, status_code
FROM
	audit_logs
WHERE
	audit_logs."time" < COALESCE((SELECT "time" FROM audit_logs a WHERE a.id = $1), $2)
ORDER BY
    "time" DESC
LIMIT
	$3
`

type GetAuditLogsBeforeParams struct {
	ID        uuid.UUID `db:"id" json:"id"`
	StartTime time.Time `db:"start_time" json:"start_time"`
	RowLimit  int32     `db:"row_limit" json:"row_limit"`
}

// GetAuditLogsBefore retrieves `limit` number of audit logs before the provided
// ID.
func (q *sqlQuerier) GetAuditLogsBefore(ctx context.Context, arg GetAuditLogsBeforeParams) ([]AuditLog, error) {
	rows, err := q.db.QueryContext(ctx, getAuditLogsBefore, arg.ID, arg.StartTime, arg.RowLimit)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []AuditLog
	for rows.Next() {
		var i AuditLog
		if err := rows.Scan(
			&i.ID,
			&i.Time,
			&i.UserID,
			&i.OrganizationID,
			&i.Ip,
			&i.UserAgent,
			&i.ResourceType,
			&i.ResourceID,
			&i.ResourceTarget,
			&i.Action,
			&i.Diff,
			&i.StatusCode,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const insertAuditLog = `-- name: InsertAuditLog :one
INSERT INTO
	audit_logs (
        id,
        "time",
        user_id,
        organization_id,
        ip,
        user_agent,
        resource_type,
        resource_id,
        resource_target,
        action,
        diff,
        status_code
    )
VALUES
	($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) RETURNING id, time, user_id, organization_id, ip, user_agent, resource_type, resource_id, resource_target, action, diff, status_code
`

type InsertAuditLogParams struct {
	ID             uuid.UUID       `db:"id" json:"id"`
	Time           time.Time       `db:"time" json:"time"`
	UserID         uuid.UUID       `db:"user_id" json:"user_id"`
	OrganizationID uuid.UUID       `db:"organization_id" json:"organization_id"`
	Ip             pqtype.Inet     `db:"ip" json:"ip"`
	UserAgent      string          `db:"user_agent" json:"user_agent"`
	ResourceType   ResourceType    `db:"resource_type" json:"resource_type"`
	ResourceID     uuid.UUID       `db:"resource_id" json:"resource_id"`
	ResourceTarget string          `db:"resource_target" json:"resource_target"`
	Action         AuditAction     `db:"action" json:"action"`
	Diff           json.RawMessage `db:"diff" json:"diff"`
	StatusCode     int32           `db:"status_code" json:"status_code"`
}

func (q *sqlQuerier) InsertAuditLog(ctx context.Context, arg InsertAuditLogParams) (AuditLog, error) {
	row := q.db.QueryRowContext(ctx, insertAuditLog,
		arg.ID,
		arg.Time,
		arg.UserID,
		arg.OrganizationID,
		arg.Ip,
		arg.UserAgent,
		arg.ResourceType,
		arg.ResourceID,
		arg.ResourceTarget,
		arg.Action,
		arg.Diff,
		arg.StatusCode,
	)
	var i AuditLog
	err := row.Scan(
		&i.ID,
		&i.Time,
		&i.UserID,
		&i.OrganizationID,
		&i.Ip,
		&i.UserAgent,
		&i.ResourceType,
		&i.ResourceID,
		&i.ResourceTarget,
		&i.Action,
		&i.Diff,
		&i.StatusCode,
	)
	return i, err
}

const getFileByHash = `-- name: GetFileByHash :one
SELECT
	hash, created_at, created_by, mimetype, data
FROM
	files
WHERE
	hash = $1
LIMIT
	1
`

func (q *sqlQuerier) GetFileByHash(ctx context.Context, hash string) (File, error) {
	row := q.db.QueryRowContext(ctx, getFileByHash, hash)
	var i File
	err := row.Scan(
		&i.Hash,
		&i.CreatedAt,
		&i.CreatedBy,
		&i.Mimetype,
		&i.Data,
	)
	return i, err
}

const insertFile = `-- name: InsertFile :one
INSERT INTO
	files (hash, created_at, created_by, mimetype, "data")
VALUES
	($1, $2, $3, $4, $5) RETURNING hash, created_at, created_by, mimetype, data
`

type InsertFileParams struct {
	Hash      string    `db:"hash" json:"hash"`
	CreatedAt time.Time `db:"created_at" json:"created_at"`
	CreatedBy uuid.UUID `db:"created_by" json:"created_by"`
	Mimetype  string    `db:"mimetype" json:"mimetype"`
	Data      []byte    `db:"data" json:"data"`
}

func (q *sqlQuerier) InsertFile(ctx context.Context, arg InsertFileParams) (File, error) {
	row := q.db.QueryRowContext(ctx, insertFile,
		arg.Hash,
		arg.CreatedAt,
		arg.CreatedBy,
		arg.Mimetype,
		arg.Data,
	)
	var i File
	err := row.Scan(
		&i.Hash,
		&i.CreatedAt,
		&i.CreatedBy,
		&i.Mimetype,
		&i.Data,
	)
	return i, err
}

const deleteGitSSHKey = `-- name: DeleteGitSSHKey :exec
DELETE FROM
	gitsshkeys
WHERE
	user_id = $1
`

func (q *sqlQuerier) DeleteGitSSHKey(ctx context.Context, userID uuid.UUID) error {
	_, err := q.db.ExecContext(ctx, deleteGitSSHKey, userID)
	return err
}

const getGitSSHKey = `-- name: GetGitSSHKey :one
SELECT
	user_id, created_at, updated_at, private_key, public_key
FROM
	gitsshkeys
WHERE
	user_id = $1
`

func (q *sqlQuerier) GetGitSSHKey(ctx context.Context, userID uuid.UUID) (GitSSHKey, error) {
	row := q.db.QueryRowContext(ctx, getGitSSHKey, userID)
	var i GitSSHKey
	err := row.Scan(
		&i.UserID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.PrivateKey,
		&i.PublicKey,
	)
	return i, err
}

const insertGitSSHKey = `-- name: InsertGitSSHKey :one
INSERT INTO
	gitsshkeys (
		user_id,
		created_at,
		updated_at,
		private_key,
		public_key
	)
VALUES
	($1, $2, $3, $4, $5) RETURNING user_id, created_at, updated_at, private_key, public_key
`

type InsertGitSSHKeyParams struct {
	UserID     uuid.UUID `db:"user_id" json:"user_id"`
	CreatedAt  time.Time `db:"created_at" json:"created_at"`
	UpdatedAt  time.Time `db:"updated_at" json:"updated_at"`
	PrivateKey string    `db:"private_key" json:"private_key"`
	PublicKey  string    `db:"public_key" json:"public_key"`
}

func (q *sqlQuerier) InsertGitSSHKey(ctx context.Context, arg InsertGitSSHKeyParams) (GitSSHKey, error) {
	row := q.db.QueryRowContext(ctx, insertGitSSHKey,
		arg.UserID,
		arg.CreatedAt,
		arg.UpdatedAt,
		arg.PrivateKey,
		arg.PublicKey,
	)
	var i GitSSHKey
	err := row.Scan(
		&i.UserID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.PrivateKey,
		&i.PublicKey,
	)
	return i, err
}

const updateGitSSHKey = `-- name: UpdateGitSSHKey :exec
UPDATE
	gitsshkeys
SET
	updated_at = $2,
	private_key = $3,
	public_key = $4
WHERE
	user_id = $1
`

type UpdateGitSSHKeyParams struct {
	UserID     uuid.UUID `db:"user_id" json:"user_id"`
	UpdatedAt  time.Time `db:"updated_at" json:"updated_at"`
	PrivateKey string    `db:"private_key" json:"private_key"`
	PublicKey  string    `db:"public_key" json:"public_key"`
}

func (q *sqlQuerier) UpdateGitSSHKey(ctx context.Context, arg UpdateGitSSHKeyParams) error {
	_, err := q.db.ExecContext(ctx, updateGitSSHKey,
		arg.UserID,
		arg.UpdatedAt,
		arg.PrivateKey,
		arg.PublicKey,
	)
	return err
}

const getLicenses = `-- name: GetLicenses :many
SELECT id, uploaded_at, jwt, exp
FROM licenses
ORDER BY (id)
`

func (q *sqlQuerier) GetLicenses(ctx context.Context) ([]License, error) {
	rows, err := q.db.QueryContext(ctx, getLicenses)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []License
	for rows.Next() {
		var i License
		if err := rows.Scan(
			&i.ID,
			&i.UploadedAt,
			&i.JWT,
			&i.Exp,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const insertLicense = `-- name: InsertLicense :one
INSERT INTO
	licenses (
	uploaded_at,
	jwt,
	exp
)
VALUES
	($1, $2, $3) RETURNING id, uploaded_at, jwt, exp
`

type InsertLicenseParams struct {
	UploadedAt time.Time `db:"uploaded_at" json:"uploaded_at"`
	JWT        string    `db:"jwt" json:"jwt"`
	Exp        time.Time `db:"exp" json:"exp"`
}

func (q *sqlQuerier) InsertLicense(ctx context.Context, arg InsertLicenseParams) (License, error) {
	row := q.db.QueryRowContext(ctx, insertLicense, arg.UploadedAt, arg.JWT, arg.Exp)
	var i License
	err := row.Scan(
		&i.ID,
		&i.UploadedAt,
		&i.JWT,
		&i.Exp,
	)
	return i, err
}

const getOrganizationIDsByMemberIDs = `-- name: GetOrganizationIDsByMemberIDs :many
SELECT
    user_id, array_agg(organization_id) :: uuid [ ] AS "organization_IDs"
FROM
    organization_members
WHERE
    user_id = ANY($1 :: uuid [ ])
GROUP BY
    user_id
`

type GetOrganizationIDsByMemberIDsRow struct {
	UserID          uuid.UUID   `db:"user_id" json:"user_id"`
	OrganizationIDs []uuid.UUID `db:"organization_IDs" json:"organization_IDs"`
}

func (q *sqlQuerier) GetOrganizationIDsByMemberIDs(ctx context.Context, ids []uuid.UUID) ([]GetOrganizationIDsByMemberIDsRow, error) {
	rows, err := q.db.QueryContext(ctx, getOrganizationIDsByMemberIDs, pq.Array(ids))
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []GetOrganizationIDsByMemberIDsRow
	for rows.Next() {
		var i GetOrganizationIDsByMemberIDsRow
		if err := rows.Scan(&i.UserID, pq.Array(&i.OrganizationIDs)); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getOrganizationMemberByUserID = `-- name: GetOrganizationMemberByUserID :one
SELECT
	user_id, organization_id, created_at, updated_at, roles
FROM
	organization_members
WHERE
	organization_id = $1
	AND user_id = $2
LIMIT
	1
`

type GetOrganizationMemberByUserIDParams struct {
	OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
	UserID         uuid.UUID `db:"user_id" json:"user_id"`
}

func (q *sqlQuerier) GetOrganizationMemberByUserID(ctx context.Context, arg GetOrganizationMemberByUserIDParams) (OrganizationMember, error) {
	row := q.db.QueryRowContext(ctx, getOrganizationMemberByUserID, arg.OrganizationID, arg.UserID)
	var i OrganizationMember
	err := row.Scan(
		&i.UserID,
		&i.OrganizationID,
		&i.CreatedAt,
		&i.UpdatedAt,
		pq.Array(&i.Roles),
	)
	return i, err
}

const getOrganizationMembershipsByUserID = `-- name: GetOrganizationMembershipsByUserID :many
SELECT
	user_id, organization_id, created_at, updated_at, roles
FROM
	organization_members
WHERE
  user_id = $1
`

func (q *sqlQuerier) GetOrganizationMembershipsByUserID(ctx context.Context, userID uuid.UUID) ([]OrganizationMember, error) {
	rows, err := q.db.QueryContext(ctx, getOrganizationMembershipsByUserID, userID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []OrganizationMember
	for rows.Next() {
		var i OrganizationMember
		if err := rows.Scan(
			&i.UserID,
			&i.OrganizationID,
			&i.CreatedAt,
			&i.UpdatedAt,
			pq.Array(&i.Roles),
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const insertOrganizationMember = `-- name: InsertOrganizationMember :one
INSERT INTO
	organization_members (
		organization_id,
		user_id,
		created_at,
		updated_at,
		roles
	)
VALUES
	($1, $2, $3, $4, $5) RETURNING user_id, organization_id, created_at, updated_at, roles
`

type InsertOrganizationMemberParams struct {
	OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
	UserID         uuid.UUID `db:"user_id" json:"user_id"`
	CreatedAt      time.Time `db:"created_at" json:"created_at"`
	UpdatedAt      time.Time `db:"updated_at" json:"updated_at"`
	Roles          []string  `db:"roles" json:"roles"`
}

func (q *sqlQuerier) InsertOrganizationMember(ctx context.Context, arg InsertOrganizationMemberParams) (OrganizationMember, error) {
	row := q.db.QueryRowContext(ctx, insertOrganizationMember,
		arg.OrganizationID,
		arg.UserID,
		arg.CreatedAt,
		arg.UpdatedAt,
		pq.Array(arg.Roles),
	)
	var i OrganizationMember
	err := row.Scan(
		&i.UserID,
		&i.OrganizationID,
		&i.CreatedAt,
		&i.UpdatedAt,
		pq.Array(&i.Roles),
	)
	return i, err
}

const updateMemberRoles = `-- name: UpdateMemberRoles :one
UPDATE
	organization_members
SET
	-- Remove all duplicates from the roles.
	roles = ARRAY(SELECT DISTINCT UNNEST($1 :: text[]))
WHERE
	user_id = $2
	AND organization_id = $3
RETURNING user_id, organization_id, created_at, updated_at, roles
`

type UpdateMemberRolesParams struct {
	GrantedRoles []string  `db:"granted_roles" json:"granted_roles"`
	UserID       uuid.UUID `db:"user_id" json:"user_id"`
	OrgID        uuid.UUID `db:"org_id" json:"org_id"`
}

func (q *sqlQuerier) UpdateMemberRoles(ctx context.Context, arg UpdateMemberRolesParams) (OrganizationMember, error) {
	row := q.db.QueryRowContext(ctx, updateMemberRoles, pq.Array(arg.GrantedRoles), arg.UserID, arg.OrgID)
	var i OrganizationMember
	err := row.Scan(
		&i.UserID,
		&i.OrganizationID,
		&i.CreatedAt,
		&i.UpdatedAt,
		pq.Array(&i.Roles),
	)
	return i, err
}

const getOrganizationByID = `-- name: GetOrganizationByID :one
SELECT
	id, name, description, created_at, updated_at
FROM
	organizations
WHERE
	id = $1
`

func (q *sqlQuerier) GetOrganizationByID(ctx context.Context, id uuid.UUID) (Organization, error) {
	row := q.db.QueryRowContext(ctx, getOrganizationByID, id)
	var i Organization
	err := row.Scan(
		&i.ID,
		&i.Name,
		&i.Description,
		&i.CreatedAt,
		&i.UpdatedAt,
	)
	return i, err
}

const getOrganizationByName = `-- name: GetOrganizationByName :one
SELECT
	id, name, description, created_at, updated_at
FROM
	organizations
WHERE
	LOWER("name") = LOWER($1)
LIMIT
	1
`

func (q *sqlQuerier) GetOrganizationByName(ctx context.Context, name string) (Organization, error) {
	row := q.db.QueryRowContext(ctx, getOrganizationByName, name)
	var i Organization
	err := row.Scan(
		&i.ID,
		&i.Name,
		&i.Description,
		&i.CreatedAt,
		&i.UpdatedAt,
	)
	return i, err
}

const getOrganizations = `-- name: GetOrganizations :many
SELECT
	id, name, description, created_at, updated_at
FROM
	organizations
`

func (q *sqlQuerier) GetOrganizations(ctx context.Context) ([]Organization, error) {
	rows, err := q.db.QueryContext(ctx, getOrganizations)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []Organization
	for rows.Next() {
		var i Organization
		if err := rows.Scan(
			&i.ID,
			&i.Name,
			&i.Description,
			&i.CreatedAt,
			&i.UpdatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getOrganizationsByUserID = `-- name: GetOrganizationsByUserID :many
SELECT
	id, name, description, created_at, updated_at
FROM
	organizations
WHERE
	id = (
		SELECT
			organization_id
		FROM
			organization_members
		WHERE
			user_id = $1
	)
`

func (q *sqlQuerier) GetOrganizationsByUserID(ctx context.Context, userID uuid.UUID) ([]Organization, error) {
	rows, err := q.db.QueryContext(ctx, getOrganizationsByUserID, userID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []Organization
	for rows.Next() {
		var i Organization
		if err := rows.Scan(
			&i.ID,
			&i.Name,
			&i.Description,
			&i.CreatedAt,
			&i.UpdatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const insertOrganization = `-- name: InsertOrganization :one
INSERT INTO
	organizations (id, "name", description, created_at, updated_at)
VALUES
	($1, $2, $3, $4, $5) RETURNING id, name, description, created_at, updated_at
`

type InsertOrganizationParams struct {
	ID          uuid.UUID `db:"id" json:"id"`
	Name        string    `db:"name" json:"name"`
	Description string    `db:"description" json:"description"`
	CreatedAt   time.Time `db:"created_at" json:"created_at"`
	UpdatedAt   time.Time `db:"updated_at" json:"updated_at"`
}

func (q *sqlQuerier) InsertOrganization(ctx context.Context, arg InsertOrganizationParams) (Organization, error) {
	row := q.db.QueryRowContext(ctx, insertOrganization,
		arg.ID,
		arg.Name,
		arg.Description,
		arg.CreatedAt,
		arg.UpdatedAt,
	)
	var i Organization
	err := row.Scan(
		&i.ID,
		&i.Name,
		&i.Description,
		&i.CreatedAt,
		&i.UpdatedAt,
	)
	return i, err
}

const getParameterSchemasByJobID = `-- name: GetParameterSchemasByJobID :many
SELECT
	id, created_at, job_id, name, description, default_source_scheme, default_source_value, allow_override_source, default_destination_scheme, allow_override_destination, default_refresh, redisplay_value, validation_error, validation_condition, validation_type_system, validation_value_type, index
FROM
	parameter_schemas
WHERE
	job_id = $1
ORDER BY
	index
`

func (q *sqlQuerier) GetParameterSchemasByJobID(ctx context.Context, jobID uuid.UUID) ([]ParameterSchema, error) {
	rows, err := q.db.QueryContext(ctx, getParameterSchemasByJobID, jobID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []ParameterSchema
	for rows.Next() {
		var i ParameterSchema
		if err := rows.Scan(
			&i.ID,
			&i.CreatedAt,
			&i.JobID,
			&i.Name,
			&i.Description,
			&i.DefaultSourceScheme,
			&i.DefaultSourceValue,
			&i.AllowOverrideSource,
			&i.DefaultDestinationScheme,
			&i.AllowOverrideDestination,
			&i.DefaultRefresh,
			&i.RedisplayValue,
			&i.ValidationError,
			&i.ValidationCondition,
			&i.ValidationTypeSystem,
			&i.ValidationValueType,
			&i.Index,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getParameterSchemasCreatedAfter = `-- name: GetParameterSchemasCreatedAfter :many
SELECT id, created_at, job_id, name, description, default_source_scheme, default_source_value, allow_override_source, default_destination_scheme, allow_override_destination, default_refresh, redisplay_value, validation_error, validation_condition, validation_type_system, validation_value_type, index FROM parameter_schemas WHERE created_at > $1
`

func (q *sqlQuerier) GetParameterSchemasCreatedAfter(ctx context.Context, createdAt time.Time) ([]ParameterSchema, error) {
	rows, err := q.db.QueryContext(ctx, getParameterSchemasCreatedAfter, createdAt)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []ParameterSchema
	for rows.Next() {
		var i ParameterSchema
		if err := rows.Scan(
			&i.ID,
			&i.CreatedAt,
			&i.JobID,
			&i.Name,
			&i.Description,
			&i.DefaultSourceScheme,
			&i.DefaultSourceValue,
			&i.AllowOverrideSource,
			&i.DefaultDestinationScheme,
			&i.AllowOverrideDestination,
			&i.DefaultRefresh,
			&i.RedisplayValue,
			&i.ValidationError,
			&i.ValidationCondition,
			&i.ValidationTypeSystem,
			&i.ValidationValueType,
			&i.Index,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const insertParameterSchema = `-- name: InsertParameterSchema :one
INSERT INTO
	parameter_schemas (
		id,
		created_at,
		job_id,
		"name",
		description,
		default_source_scheme,
		default_source_value,
		allow_override_source,
		default_destination_scheme,
		allow_override_destination,
		default_refresh,
		redisplay_value,
		validation_error,
		validation_condition,
		validation_type_system,
		validation_value_type,
		index
	)
VALUES
	(
		$1,
		$2,
		$3,
		$4,
		$5,
		$6,
		$7,
		$8,
		$9,
		$10,
		$11,
		$12,
		$13,
		$14,
		$15,
		$16,
		$17
	) RETURNING id, created_at, job_id, name, description, default_source_scheme, default_source_value, allow_override_source, default_destination_scheme, allow_override_destination, default_refresh, redisplay_value, validation_error, validation_condition, validation_type_system, validation_value_type, index
`

type InsertParameterSchemaParams struct {
	ID                       uuid.UUID                  `db:"id" json:"id"`
	CreatedAt                time.Time                  `db:"created_at" json:"created_at"`
	JobID                    uuid.UUID                  `db:"job_id" json:"job_id"`
	Name                     string                     `db:"name" json:"name"`
	Description              string                     `db:"description" json:"description"`
	DefaultSourceScheme      ParameterSourceScheme      `db:"default_source_scheme" json:"default_source_scheme"`
	DefaultSourceValue       string                     `db:"default_source_value" json:"default_source_value"`
	AllowOverrideSource      bool                       `db:"allow_override_source" json:"allow_override_source"`
	DefaultDestinationScheme ParameterDestinationScheme `db:"default_destination_scheme" json:"default_destination_scheme"`
	AllowOverrideDestination bool                       `db:"allow_override_destination" json:"allow_override_destination"`
	DefaultRefresh           string                     `db:"default_refresh" json:"default_refresh"`
	RedisplayValue           bool                       `db:"redisplay_value" json:"redisplay_value"`
	ValidationError          string                     `db:"validation_error" json:"validation_error"`
	ValidationCondition      string                     `db:"validation_condition" json:"validation_condition"`
	ValidationTypeSystem     ParameterTypeSystem        `db:"validation_type_system" json:"validation_type_system"`
	ValidationValueType      string                     `db:"validation_value_type" json:"validation_value_type"`
	Index                    int32                      `db:"index" json:"index"`
}

func (q *sqlQuerier) InsertParameterSchema(ctx context.Context, arg InsertParameterSchemaParams) (ParameterSchema, error) {
	row := q.db.QueryRowContext(ctx, insertParameterSchema,
		arg.ID,
		arg.CreatedAt,
		arg.JobID,
		arg.Name,
		arg.Description,
		arg.DefaultSourceScheme,
		arg.DefaultSourceValue,
		arg.AllowOverrideSource,
		arg.DefaultDestinationScheme,
		arg.AllowOverrideDestination,
		arg.DefaultRefresh,
		arg.RedisplayValue,
		arg.ValidationError,
		arg.ValidationCondition,
		arg.ValidationTypeSystem,
		arg.ValidationValueType,
		arg.Index,
	)
	var i ParameterSchema
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.JobID,
		&i.Name,
		&i.Description,
		&i.DefaultSourceScheme,
		&i.DefaultSourceValue,
		&i.AllowOverrideSource,
		&i.DefaultDestinationScheme,
		&i.AllowOverrideDestination,
		&i.DefaultRefresh,
		&i.RedisplayValue,
		&i.ValidationError,
		&i.ValidationCondition,
		&i.ValidationTypeSystem,
		&i.ValidationValueType,
		&i.Index,
	)
	return i, err
}

const deleteParameterValueByID = `-- name: DeleteParameterValueByID :exec
DELETE FROM
	parameter_values
WHERE
	id = $1
`

func (q *sqlQuerier) DeleteParameterValueByID(ctx context.Context, id uuid.UUID) error {
	_, err := q.db.ExecContext(ctx, deleteParameterValueByID, id)
	return err
}

const getParameterValueByScopeAndName = `-- name: GetParameterValueByScopeAndName :one
SELECT
	id, created_at, updated_at, scope, scope_id, name, source_scheme, source_value, destination_scheme
FROM
	parameter_values
WHERE
	scope = $1
	AND scope_id = $2
	AND NAME = $3
LIMIT
	1
`

type GetParameterValueByScopeAndNameParams struct {
	Scope   ParameterScope `db:"scope" json:"scope"`
	ScopeID uuid.UUID      `db:"scope_id" json:"scope_id"`
	Name    string         `db:"name" json:"name"`
}

func (q *sqlQuerier) GetParameterValueByScopeAndName(ctx context.Context, arg GetParameterValueByScopeAndNameParams) (ParameterValue, error) {
	row := q.db.QueryRowContext(ctx, getParameterValueByScopeAndName, arg.Scope, arg.ScopeID, arg.Name)
	var i ParameterValue
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Scope,
		&i.ScopeID,
		&i.Name,
		&i.SourceScheme,
		&i.SourceValue,
		&i.DestinationScheme,
	)
	return i, err
}

const insertParameterValue = `-- name: InsertParameterValue :one
INSERT INTO
	parameter_values (
		id,
		"name",
		created_at,
		updated_at,
		scope,
		scope_id,
		source_scheme,
		source_value,
		destination_scheme
	)
VALUES
	($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING id, created_at, updated_at, scope, scope_id, name, source_scheme, source_value, destination_scheme
`

type InsertParameterValueParams struct {
	ID                uuid.UUID                  `db:"id" json:"id"`
	Name              string                     `db:"name" json:"name"`
	CreatedAt         time.Time                  `db:"created_at" json:"created_at"`
	UpdatedAt         time.Time                  `db:"updated_at" json:"updated_at"`
	Scope             ParameterScope             `db:"scope" json:"scope"`
	ScopeID           uuid.UUID                  `db:"scope_id" json:"scope_id"`
	SourceScheme      ParameterSourceScheme      `db:"source_scheme" json:"source_scheme"`
	SourceValue       string                     `db:"source_value" json:"source_value"`
	DestinationScheme ParameterDestinationScheme `db:"destination_scheme" json:"destination_scheme"`
}

func (q *sqlQuerier) InsertParameterValue(ctx context.Context, arg InsertParameterValueParams) (ParameterValue, error) {
	row := q.db.QueryRowContext(ctx, insertParameterValue,
		arg.ID,
		arg.Name,
		arg.CreatedAt,
		arg.UpdatedAt,
		arg.Scope,
		arg.ScopeID,
		arg.SourceScheme,
		arg.SourceValue,
		arg.DestinationScheme,
	)
	var i ParameterValue
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Scope,
		&i.ScopeID,
		&i.Name,
		&i.SourceScheme,
		&i.SourceValue,
		&i.DestinationScheme,
	)
	return i, err
}

const parameterValue = `-- name: ParameterValue :one
SELECT id, created_at, updated_at, scope, scope_id, name, source_scheme, source_value, destination_scheme FROM
	parameter_values
WHERE
	id = $1
`

func (q *sqlQuerier) ParameterValue(ctx context.Context, id uuid.UUID) (ParameterValue, error) {
	row := q.db.QueryRowContext(ctx, parameterValue, id)
	var i ParameterValue
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Scope,
		&i.ScopeID,
		&i.Name,
		&i.SourceScheme,
		&i.SourceValue,
		&i.DestinationScheme,
	)
	return i, err
}

const parameterValues = `-- name: ParameterValues :many
SELECT
	id, created_at, updated_at, scope, scope_id, name, source_scheme, source_value, destination_scheme
FROM
	parameter_values
WHERE
  	CASE
		  WHEN cardinality($1 :: parameter_scope[]) > 0 THEN
				  scope = ANY($1 :: parameter_scope[])
		  ELSE true
	END
    AND CASE
		WHEN cardinality($2 :: uuid[]) > 0 THEN
			scope_id = ANY($2 :: uuid[])
		ELSE true
	END
  	AND CASE
		WHEN cardinality($3 :: uuid[]) > 0 THEN
			id = ANY($3 :: uuid[])
		ELSE true
	END
  	AND CASE
		  WHEN cardinality($4 :: text[]) > 0 THEN
				  "name" = ANY($4 :: text[])
		  ELSE true
	END
`

type ParameterValuesParams struct {
	Scopes   []ParameterScope `db:"scopes" json:"scopes"`
	ScopeIds []uuid.UUID      `db:"scope_ids" json:"scope_ids"`
	Ids      []uuid.UUID      `db:"ids" json:"ids"`
	Names    []string         `db:"names" json:"names"`
}

func (q *sqlQuerier) ParameterValues(ctx context.Context, arg ParameterValuesParams) ([]ParameterValue, error) {
	rows, err := q.db.QueryContext(ctx, parameterValues,
		pq.Array(arg.Scopes),
		pq.Array(arg.ScopeIds),
		pq.Array(arg.Ids),
		pq.Array(arg.Names),
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []ParameterValue
	for rows.Next() {
		var i ParameterValue
		if err := rows.Scan(
			&i.ID,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.Scope,
			&i.ScopeID,
			&i.Name,
			&i.SourceScheme,
			&i.SourceValue,
			&i.DestinationScheme,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getProvisionerDaemonByID = `-- name: GetProvisionerDaemonByID :one
SELECT
	id, created_at, updated_at, name, provisioners
FROM
	provisioner_daemons
WHERE
	id = $1
`

func (q *sqlQuerier) GetProvisionerDaemonByID(ctx context.Context, id uuid.UUID) (ProvisionerDaemon, error) {
	row := q.db.QueryRowContext(ctx, getProvisionerDaemonByID, id)
	var i ProvisionerDaemon
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Name,
		pq.Array(&i.Provisioners),
	)
	return i, err
}

const getProvisionerDaemons = `-- name: GetProvisionerDaemons :many
SELECT
	id, created_at, updated_at, name, provisioners
FROM
	provisioner_daemons
`

func (q *sqlQuerier) GetProvisionerDaemons(ctx context.Context) ([]ProvisionerDaemon, error) {
	rows, err := q.db.QueryContext(ctx, getProvisionerDaemons)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []ProvisionerDaemon
	for rows.Next() {
		var i ProvisionerDaemon
		if err := rows.Scan(
			&i.ID,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.Name,
			pq.Array(&i.Provisioners),
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const insertProvisionerDaemon = `-- name: InsertProvisionerDaemon :one
INSERT INTO
	provisioner_daemons (
		id,
		created_at,
		"name",
		provisioners
	)
VALUES
	($1, $2, $3, $4) RETURNING id, created_at, updated_at, name, provisioners
`

type InsertProvisionerDaemonParams struct {
	ID           uuid.UUID         `db:"id" json:"id"`
	CreatedAt    time.Time         `db:"created_at" json:"created_at"`
	Name         string            `db:"name" json:"name"`
	Provisioners []ProvisionerType `db:"provisioners" json:"provisioners"`
}

func (q *sqlQuerier) InsertProvisionerDaemon(ctx context.Context, arg InsertProvisionerDaemonParams) (ProvisionerDaemon, error) {
	row := q.db.QueryRowContext(ctx, insertProvisionerDaemon,
		arg.ID,
		arg.CreatedAt,
		arg.Name,
		pq.Array(arg.Provisioners),
	)
	var i ProvisionerDaemon
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Name,
		pq.Array(&i.Provisioners),
	)
	return i, err
}

const updateProvisionerDaemonByID = `-- name: UpdateProvisionerDaemonByID :exec
UPDATE
	provisioner_daemons
SET
	updated_at = $2,
	provisioners = $3
WHERE
	id = $1
`

type UpdateProvisionerDaemonByIDParams struct {
	ID           uuid.UUID         `db:"id" json:"id"`
	UpdatedAt    sql.NullTime      `db:"updated_at" json:"updated_at"`
	Provisioners []ProvisionerType `db:"provisioners" json:"provisioners"`
}

func (q *sqlQuerier) UpdateProvisionerDaemonByID(ctx context.Context, arg UpdateProvisionerDaemonByIDParams) error {
	_, err := q.db.ExecContext(ctx, updateProvisionerDaemonByID, arg.ID, arg.UpdatedAt, pq.Array(arg.Provisioners))
	return err
}

const getProvisionerLogsByIDBetween = `-- name: GetProvisionerLogsByIDBetween :many
SELECT
	id, job_id, created_at, source, level, stage, output
FROM
	provisioner_job_logs
WHERE
	job_id = $1
	AND (
		created_at >= $2
		OR created_at <= $3
	)
ORDER BY
	created_at DESC
`

type GetProvisionerLogsByIDBetweenParams struct {
	JobID         uuid.UUID `db:"job_id" json:"job_id"`
	CreatedAfter  time.Time `db:"created_after" json:"created_after"`
	CreatedBefore time.Time `db:"created_before" json:"created_before"`
}

func (q *sqlQuerier) GetProvisionerLogsByIDBetween(ctx context.Context, arg GetProvisionerLogsByIDBetweenParams) ([]ProvisionerJobLog, error) {
	rows, err := q.db.QueryContext(ctx, getProvisionerLogsByIDBetween, arg.JobID, arg.CreatedAfter, arg.CreatedBefore)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []ProvisionerJobLog
	for rows.Next() {
		var i ProvisionerJobLog
		if err := rows.Scan(
			&i.ID,
			&i.JobID,
			&i.CreatedAt,
			&i.Source,
			&i.Level,
			&i.Stage,
			&i.Output,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const insertProvisionerJobLogs = `-- name: InsertProvisionerJobLogs :many
INSERT INTO
	provisioner_job_logs
SELECT
	unnest($1 :: uuid [ ]) AS id,
	$2 :: uuid AS job_id,
	unnest($3 :: timestamptz [ ]) AS created_at,
	unnest($4 :: log_source [ ]) AS source,
	unnest($5 :: log_level [ ]) AS LEVEL,
	unnest($6 :: VARCHAR(128) [ ]) AS stage,
	unnest($7 :: VARCHAR(1024) [ ]) AS output RETURNING id, job_id, created_at, source, level, stage, output
`

type InsertProvisionerJobLogsParams struct {
	ID        []uuid.UUID `db:"id" json:"id"`
	JobID     uuid.UUID   `db:"job_id" json:"job_id"`
	CreatedAt []time.Time `db:"created_at" json:"created_at"`
	Source    []LogSource `db:"source" json:"source"`
	Level     []LogLevel  `db:"level" json:"level"`
	Stage     []string    `db:"stage" json:"stage"`
	Output    []string    `db:"output" json:"output"`
}

func (q *sqlQuerier) InsertProvisionerJobLogs(ctx context.Context, arg InsertProvisionerJobLogsParams) ([]ProvisionerJobLog, error) {
	rows, err := q.db.QueryContext(ctx, insertProvisionerJobLogs,
		pq.Array(arg.ID),
		arg.JobID,
		pq.Array(arg.CreatedAt),
		pq.Array(arg.Source),
		pq.Array(arg.Level),
		pq.Array(arg.Stage),
		pq.Array(arg.Output),
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []ProvisionerJobLog
	for rows.Next() {
		var i ProvisionerJobLog
		if err := rows.Scan(
			&i.ID,
			&i.JobID,
			&i.CreatedAt,
			&i.Source,
			&i.Level,
			&i.Stage,
			&i.Output,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const acquireProvisionerJob = `-- name: AcquireProvisionerJob :one
UPDATE
	provisioner_jobs
SET
	started_at = $1,
	updated_at = $1,
	worker_id = $2
WHERE
	id = (
		SELECT
			id
		FROM
			provisioner_jobs AS nested
		WHERE
			nested.started_at IS NULL
			AND nested.canceled_at IS NULL
			AND nested.completed_at IS NULL
			AND nested.provisioner = ANY($3 :: provisioner_type [ ])
		ORDER BY
			nested.created_at FOR
		UPDATE
			SKIP LOCKED
		LIMIT
			1
	) RETURNING id, created_at, updated_at, started_at, canceled_at, completed_at, error, organization_id, initiator_id, provisioner, storage_method, storage_source, type, input, worker_id
`

type AcquireProvisionerJobParams struct {
	StartedAt sql.NullTime      `db:"started_at" json:"started_at"`
	WorkerID  uuid.NullUUID     `db:"worker_id" json:"worker_id"`
	Types     []ProvisionerType `db:"types" json:"types"`
}

// Acquires the lock for a single job that isn't started, completed,
// canceled, and that matches an array of provisioner types.
//
// SKIP LOCKED is used to jump over locked rows. This prevents
// multiple provisioners from acquiring the same jobs. See:
// https://www.postgresql.org/docs/9.5/sql-select.html#SQL-FOR-UPDATE-SHARE
func (q *sqlQuerier) AcquireProvisionerJob(ctx context.Context, arg AcquireProvisionerJobParams) (ProvisionerJob, error) {
	row := q.db.QueryRowContext(ctx, acquireProvisionerJob, arg.StartedAt, arg.WorkerID, pq.Array(arg.Types))
	var i ProvisionerJob
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.StartedAt,
		&i.CanceledAt,
		&i.CompletedAt,
		&i.Error,
		&i.OrganizationID,
		&i.InitiatorID,
		&i.Provisioner,
		&i.StorageMethod,
		&i.StorageSource,
		&i.Type,
		&i.Input,
		&i.WorkerID,
	)
	return i, err
}

const getProvisionerJobByID = `-- name: GetProvisionerJobByID :one
SELECT
	id, created_at, updated_at, started_at, canceled_at, completed_at, error, organization_id, initiator_id, provisioner, storage_method, storage_source, type, input, worker_id
FROM
	provisioner_jobs
WHERE
	id = $1
`

func (q *sqlQuerier) GetProvisionerJobByID(ctx context.Context, id uuid.UUID) (ProvisionerJob, error) {
	row := q.db.QueryRowContext(ctx, getProvisionerJobByID, id)
	var i ProvisionerJob
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.StartedAt,
		&i.CanceledAt,
		&i.CompletedAt,
		&i.Error,
		&i.OrganizationID,
		&i.InitiatorID,
		&i.Provisioner,
		&i.StorageMethod,
		&i.StorageSource,
		&i.Type,
		&i.Input,
		&i.WorkerID,
	)
	return i, err
}

const getProvisionerJobsByIDs = `-- name: GetProvisionerJobsByIDs :many
SELECT
	id, created_at, updated_at, started_at, canceled_at, completed_at, error, organization_id, initiator_id, provisioner, storage_method, storage_source, type, input, worker_id
FROM
	provisioner_jobs
WHERE
	id = ANY($1 :: uuid [ ])
`

func (q *sqlQuerier) GetProvisionerJobsByIDs(ctx context.Context, ids []uuid.UUID) ([]ProvisionerJob, error) {
	rows, err := q.db.QueryContext(ctx, getProvisionerJobsByIDs, pq.Array(ids))
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []ProvisionerJob
	for rows.Next() {
		var i ProvisionerJob
		if err := rows.Scan(
			&i.ID,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.StartedAt,
			&i.CanceledAt,
			&i.CompletedAt,
			&i.Error,
			&i.OrganizationID,
			&i.InitiatorID,
			&i.Provisioner,
			&i.StorageMethod,
			&i.StorageSource,
			&i.Type,
			&i.Input,
			&i.WorkerID,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getProvisionerJobsCreatedAfter = `-- name: GetProvisionerJobsCreatedAfter :many
SELECT id, created_at, updated_at, started_at, canceled_at, completed_at, error, organization_id, initiator_id, provisioner, storage_method, storage_source, type, input, worker_id FROM provisioner_jobs WHERE created_at > $1
`

func (q *sqlQuerier) GetProvisionerJobsCreatedAfter(ctx context.Context, createdAt time.Time) ([]ProvisionerJob, error) {
	rows, err := q.db.QueryContext(ctx, getProvisionerJobsCreatedAfter, createdAt)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []ProvisionerJob
	for rows.Next() {
		var i ProvisionerJob
		if err := rows.Scan(
			&i.ID,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.StartedAt,
			&i.CanceledAt,
			&i.CompletedAt,
			&i.Error,
			&i.OrganizationID,
			&i.InitiatorID,
			&i.Provisioner,
			&i.StorageMethod,
			&i.StorageSource,
			&i.Type,
			&i.Input,
			&i.WorkerID,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const insertProvisionerJob = `-- name: InsertProvisionerJob :one
INSERT INTO
	provisioner_jobs (
		id,
		created_at,
		updated_at,
		organization_id,
		initiator_id,
		provisioner,
		storage_method,
		storage_source,
		"type",
		"input"
	)
VALUES
	($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING id, created_at, updated_at, started_at, canceled_at, completed_at, error, organization_id, initiator_id, provisioner, storage_method, storage_source, type, input, worker_id
`

type InsertProvisionerJobParams struct {
	ID             uuid.UUID                `db:"id" json:"id"`
	CreatedAt      time.Time                `db:"created_at" json:"created_at"`
	UpdatedAt      time.Time                `db:"updated_at" json:"updated_at"`
	OrganizationID uuid.UUID                `db:"organization_id" json:"organization_id"`
	InitiatorID    uuid.UUID                `db:"initiator_id" json:"initiator_id"`
	Provisioner    ProvisionerType          `db:"provisioner" json:"provisioner"`
	StorageMethod  ProvisionerStorageMethod `db:"storage_method" json:"storage_method"`
	StorageSource  string                   `db:"storage_source" json:"storage_source"`
	Type           ProvisionerJobType       `db:"type" json:"type"`
	Input          json.RawMessage          `db:"input" json:"input"`
}

func (q *sqlQuerier) InsertProvisionerJob(ctx context.Context, arg InsertProvisionerJobParams) (ProvisionerJob, error) {
	row := q.db.QueryRowContext(ctx, insertProvisionerJob,
		arg.ID,
		arg.CreatedAt,
		arg.UpdatedAt,
		arg.OrganizationID,
		arg.InitiatorID,
		arg.Provisioner,
		arg.StorageMethod,
		arg.StorageSource,
		arg.Type,
		arg.Input,
	)
	var i ProvisionerJob
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.StartedAt,
		&i.CanceledAt,
		&i.CompletedAt,
		&i.Error,
		&i.OrganizationID,
		&i.InitiatorID,
		&i.Provisioner,
		&i.StorageMethod,
		&i.StorageSource,
		&i.Type,
		&i.Input,
		&i.WorkerID,
	)
	return i, err
}

const updateProvisionerJobByID = `-- name: UpdateProvisionerJobByID :exec
UPDATE
	provisioner_jobs
SET
	updated_at = $2
WHERE
	id = $1
`

type UpdateProvisionerJobByIDParams struct {
	ID        uuid.UUID `db:"id" json:"id"`
	UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
}

func (q *sqlQuerier) UpdateProvisionerJobByID(ctx context.Context, arg UpdateProvisionerJobByIDParams) error {
	_, err := q.db.ExecContext(ctx, updateProvisionerJobByID, arg.ID, arg.UpdatedAt)
	return err
}

const updateProvisionerJobWithCancelByID = `-- name: UpdateProvisionerJobWithCancelByID :exec
UPDATE
	provisioner_jobs
SET
	canceled_at = $2
WHERE
	id = $1
`

type UpdateProvisionerJobWithCancelByIDParams struct {
	ID         uuid.UUID    `db:"id" json:"id"`
	CanceledAt sql.NullTime `db:"canceled_at" json:"canceled_at"`
}

func (q *sqlQuerier) UpdateProvisionerJobWithCancelByID(ctx context.Context, arg UpdateProvisionerJobWithCancelByIDParams) error {
	_, err := q.db.ExecContext(ctx, updateProvisionerJobWithCancelByID, arg.ID, arg.CanceledAt)
	return err
}

const updateProvisionerJobWithCompleteByID = `-- name: UpdateProvisionerJobWithCompleteByID :exec
UPDATE
	provisioner_jobs
SET
	updated_at = $2,
	completed_at = $3,
	error = $4
WHERE
	id = $1
`

type UpdateProvisionerJobWithCompleteByIDParams struct {
	ID          uuid.UUID      `db:"id" json:"id"`
	UpdatedAt   time.Time      `db:"updated_at" json:"updated_at"`
	CompletedAt sql.NullTime   `db:"completed_at" json:"completed_at"`
	Error       sql.NullString `db:"error" json:"error"`
}

func (q *sqlQuerier) UpdateProvisionerJobWithCompleteByID(ctx context.Context, arg UpdateProvisionerJobWithCompleteByIDParams) error {
	_, err := q.db.ExecContext(ctx, updateProvisionerJobWithCompleteByID,
		arg.ID,
		arg.UpdatedAt,
		arg.CompletedAt,
		arg.Error,
	)
	return err
}

const getDeploymentID = `-- name: GetDeploymentID :one
SELECT value FROM site_configs WHERE key = 'deployment_id'
`

func (q *sqlQuerier) GetDeploymentID(ctx context.Context) (string, error) {
	row := q.db.QueryRowContext(ctx, getDeploymentID)
	var value string
	err := row.Scan(&value)
	return value, err
}

const insertDeploymentID = `-- name: InsertDeploymentID :exec
INSERT INTO site_configs (key, value) VALUES ('deployment_id', $1)
`

func (q *sqlQuerier) InsertDeploymentID(ctx context.Context, value string) error {
	_, err := q.db.ExecContext(ctx, insertDeploymentID, value)
	return err
}

const getTemplateByID = `-- name: GetTemplateByID :one
SELECT
	id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, created_by, icon
FROM
	templates
WHERE
	id = $1
LIMIT
	1
`

func (q *sqlQuerier) GetTemplateByID(ctx context.Context, id uuid.UUID) (Template, error) {
	row := q.db.QueryRowContext(ctx, getTemplateByID, id)
	var i Template
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.OrganizationID,
		&i.Deleted,
		&i.Name,
		&i.Provisioner,
		&i.ActiveVersionID,
		&i.Description,
		&i.MaxTtl,
		&i.MinAutostartInterval,
		&i.CreatedBy,
		&i.Icon,
	)
	return i, err
}

const getTemplateByOrganizationAndName = `-- name: GetTemplateByOrganizationAndName :one
SELECT
	id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, created_by, icon
FROM
	templates
WHERE
	organization_id = $1
	AND deleted = $2
	AND LOWER("name") = LOWER($3)
LIMIT
	1
`

type GetTemplateByOrganizationAndNameParams struct {
	OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
	Deleted        bool      `db:"deleted" json:"deleted"`
	Name           string    `db:"name" json:"name"`
}

func (q *sqlQuerier) GetTemplateByOrganizationAndName(ctx context.Context, arg GetTemplateByOrganizationAndNameParams) (Template, error) {
	row := q.db.QueryRowContext(ctx, getTemplateByOrganizationAndName, arg.OrganizationID, arg.Deleted, arg.Name)
	var i Template
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.OrganizationID,
		&i.Deleted,
		&i.Name,
		&i.Provisioner,
		&i.ActiveVersionID,
		&i.Description,
		&i.MaxTtl,
		&i.MinAutostartInterval,
		&i.CreatedBy,
		&i.Icon,
	)
	return i, err
}

const getTemplates = `-- name: GetTemplates :many
SELECT id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, created_by, icon FROM templates
ORDER BY (name, id) ASC
`

func (q *sqlQuerier) GetTemplates(ctx context.Context) ([]Template, error) {
	rows, err := q.db.QueryContext(ctx, getTemplates)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []Template
	for rows.Next() {
		var i Template
		if err := rows.Scan(
			&i.ID,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.OrganizationID,
			&i.Deleted,
			&i.Name,
			&i.Provisioner,
			&i.ActiveVersionID,
			&i.Description,
			&i.MaxTtl,
			&i.MinAutostartInterval,
			&i.CreatedBy,
			&i.Icon,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getTemplatesWithFilter = `-- name: GetTemplatesWithFilter :many
SELECT
	id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, created_by, icon
FROM
	templates
WHERE
	-- Optionally include deleted templates
	templates.deleted = $1
	-- Filter by organization_id
	AND CASE
		WHEN $2 :: uuid != '00000000-00000000-00000000-00000000' THEN
			organization_id = $2
		ELSE true
	END
	-- Filter by exact name
	AND CASE
		WHEN $3 :: text != '' THEN
			LOWER("name") = LOWER($3)
		ELSE true
	END
	-- Filter by ids
	AND CASE
		WHEN array_length($4 :: uuid[], 1) > 0 THEN
			id = ANY($4)
		ELSE true
	END
ORDER BY (name, id) ASC
`

type GetTemplatesWithFilterParams struct {
	Deleted        bool        `db:"deleted" json:"deleted"`
	OrganizationID uuid.UUID   `db:"organization_id" json:"organization_id"`
	ExactName      string      `db:"exact_name" json:"exact_name"`
	Ids            []uuid.UUID `db:"ids" json:"ids"`
}

func (q *sqlQuerier) GetTemplatesWithFilter(ctx context.Context, arg GetTemplatesWithFilterParams) ([]Template, error) {
	rows, err := q.db.QueryContext(ctx, getTemplatesWithFilter,
		arg.Deleted,
		arg.OrganizationID,
		arg.ExactName,
		pq.Array(arg.Ids),
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []Template
	for rows.Next() {
		var i Template
		if err := rows.Scan(
			&i.ID,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.OrganizationID,
			&i.Deleted,
			&i.Name,
			&i.Provisioner,
			&i.ActiveVersionID,
			&i.Description,
			&i.MaxTtl,
			&i.MinAutostartInterval,
			&i.CreatedBy,
			&i.Icon,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const insertTemplate = `-- name: InsertTemplate :one
INSERT INTO
	templates (
		id,
		created_at,
		updated_at,
		organization_id,
		"name",
		provisioner,
		active_version_id,
		description,
		max_ttl,
		min_autostart_interval,
		created_by,
		icon
	)
VALUES
	($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) RETURNING id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, created_by, icon
`

type InsertTemplateParams struct {
	ID                   uuid.UUID       `db:"id" json:"id"`
	CreatedAt            time.Time       `db:"created_at" json:"created_at"`
	UpdatedAt            time.Time       `db:"updated_at" json:"updated_at"`
	OrganizationID       uuid.UUID       `db:"organization_id" json:"organization_id"`
	Name                 string          `db:"name" json:"name"`
	Provisioner          ProvisionerType `db:"provisioner" json:"provisioner"`
	ActiveVersionID      uuid.UUID       `db:"active_version_id" json:"active_version_id"`
	Description          string          `db:"description" json:"description"`
	MaxTtl               int64           `db:"max_ttl" json:"max_ttl"`
	MinAutostartInterval int64           `db:"min_autostart_interval" json:"min_autostart_interval"`
	CreatedBy            uuid.UUID       `db:"created_by" json:"created_by"`
	Icon                 string          `db:"icon" json:"icon"`
}

func (q *sqlQuerier) InsertTemplate(ctx context.Context, arg InsertTemplateParams) (Template, error) {
	row := q.db.QueryRowContext(ctx, insertTemplate,
		arg.ID,
		arg.CreatedAt,
		arg.UpdatedAt,
		arg.OrganizationID,
		arg.Name,
		arg.Provisioner,
		arg.ActiveVersionID,
		arg.Description,
		arg.MaxTtl,
		arg.MinAutostartInterval,
		arg.CreatedBy,
		arg.Icon,
	)
	var i Template
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.OrganizationID,
		&i.Deleted,
		&i.Name,
		&i.Provisioner,
		&i.ActiveVersionID,
		&i.Description,
		&i.MaxTtl,
		&i.MinAutostartInterval,
		&i.CreatedBy,
		&i.Icon,
	)
	return i, err
}

const updateTemplateActiveVersionByID = `-- name: UpdateTemplateActiveVersionByID :exec
UPDATE
	templates
SET
	active_version_id = $2,
	updated_at = $3
WHERE
	id = $1
`

type UpdateTemplateActiveVersionByIDParams struct {
	ID              uuid.UUID `db:"id" json:"id"`
	ActiveVersionID uuid.UUID `db:"active_version_id" json:"active_version_id"`
	UpdatedAt       time.Time `db:"updated_at" json:"updated_at"`
}

func (q *sqlQuerier) UpdateTemplateActiveVersionByID(ctx context.Context, arg UpdateTemplateActiveVersionByIDParams) error {
	_, err := q.db.ExecContext(ctx, updateTemplateActiveVersionByID, arg.ID, arg.ActiveVersionID, arg.UpdatedAt)
	return err
}

const updateTemplateDeletedByID = `-- name: UpdateTemplateDeletedByID :exec
UPDATE
	templates
SET
	deleted = $2,
	updated_at = $3
WHERE
	id = $1
`

type UpdateTemplateDeletedByIDParams struct {
	ID        uuid.UUID `db:"id" json:"id"`
	Deleted   bool      `db:"deleted" json:"deleted"`
	UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
}

func (q *sqlQuerier) UpdateTemplateDeletedByID(ctx context.Context, arg UpdateTemplateDeletedByIDParams) error {
	_, err := q.db.ExecContext(ctx, updateTemplateDeletedByID, arg.ID, arg.Deleted, arg.UpdatedAt)
	return err
}

const updateTemplateMetaByID = `-- name: UpdateTemplateMetaByID :exec
UPDATE
	templates
SET
	updated_at = $2,
	description = $3,
	max_ttl = $4,
	min_autostart_interval = $5,
	name = $6,
	icon = $7
WHERE
	id = $1
RETURNING
	id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, created_by, icon
`

type UpdateTemplateMetaByIDParams struct {
	ID                   uuid.UUID `db:"id" json:"id"`
	UpdatedAt            time.Time `db:"updated_at" json:"updated_at"`
	Description          string    `db:"description" json:"description"`
	MaxTtl               int64     `db:"max_ttl" json:"max_ttl"`
	MinAutostartInterval int64     `db:"min_autostart_interval" json:"min_autostart_interval"`
	Name                 string    `db:"name" json:"name"`
	Icon                 string    `db:"icon" json:"icon"`
}

func (q *sqlQuerier) UpdateTemplateMetaByID(ctx context.Context, arg UpdateTemplateMetaByIDParams) error {
	_, err := q.db.ExecContext(ctx, updateTemplateMetaByID,
		arg.ID,
		arg.UpdatedAt,
		arg.Description,
		arg.MaxTtl,
		arg.MinAutostartInterval,
		arg.Name,
		arg.Icon,
	)
	return err
}

const getTemplateVersionByID = `-- name: GetTemplateVersionByID :one
SELECT
	id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by
FROM
	template_versions
WHERE
	id = $1
`

func (q *sqlQuerier) GetTemplateVersionByID(ctx context.Context, id uuid.UUID) (TemplateVersion, error) {
	row := q.db.QueryRowContext(ctx, getTemplateVersionByID, id)
	var i TemplateVersion
	err := row.Scan(
		&i.ID,
		&i.TemplateID,
		&i.OrganizationID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Name,
		&i.Readme,
		&i.JobID,
		&i.CreatedBy,
	)
	return i, err
}

const getTemplateVersionByJobID = `-- name: GetTemplateVersionByJobID :one
SELECT
	id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by
FROM
	template_versions
WHERE
	job_id = $1
`

func (q *sqlQuerier) GetTemplateVersionByJobID(ctx context.Context, jobID uuid.UUID) (TemplateVersion, error) {
	row := q.db.QueryRowContext(ctx, getTemplateVersionByJobID, jobID)
	var i TemplateVersion
	err := row.Scan(
		&i.ID,
		&i.TemplateID,
		&i.OrganizationID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Name,
		&i.Readme,
		&i.JobID,
		&i.CreatedBy,
	)
	return i, err
}

const getTemplateVersionByTemplateIDAndName = `-- name: GetTemplateVersionByTemplateIDAndName :one
SELECT
	id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by
FROM
	template_versions
WHERE
	template_id = $1
	AND "name" = $2
`

type GetTemplateVersionByTemplateIDAndNameParams struct {
	TemplateID uuid.NullUUID `db:"template_id" json:"template_id"`
	Name       string        `db:"name" json:"name"`
}

func (q *sqlQuerier) GetTemplateVersionByTemplateIDAndName(ctx context.Context, arg GetTemplateVersionByTemplateIDAndNameParams) (TemplateVersion, error) {
	row := q.db.QueryRowContext(ctx, getTemplateVersionByTemplateIDAndName, arg.TemplateID, arg.Name)
	var i TemplateVersion
	err := row.Scan(
		&i.ID,
		&i.TemplateID,
		&i.OrganizationID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Name,
		&i.Readme,
		&i.JobID,
		&i.CreatedBy,
	)
	return i, err
}

const getTemplateVersionsByTemplateID = `-- name: GetTemplateVersionsByTemplateID :many
SELECT
	id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by
FROM
	template_versions
WHERE
	template_id = $1 :: uuid
	AND CASE
		-- This allows using the last element on a page as effectively a cursor.
		-- This is an important option for scripts that need to paginate without
		-- duplicating or missing data.
		WHEN $2 :: uuid != '00000000-00000000-00000000-00000000' THEN (
			-- The pagination cursor is the last ID of the previous page.
			-- The query is ordered by the created_at field, so select all
			-- rows after the cursor.
			(created_at, id) > (
				SELECT
					created_at, id
				FROM
					template_versions
				WHERE
					id = $2
			)
		)
		ELSE true
	END
ORDER BY
    -- Deterministic and consistent ordering of all rows, even if they share
    -- a timestamp. This is to ensure consistent pagination.
	(created_at, id) ASC OFFSET $3
LIMIT
	-- A null limit means "no limit", so 0 means return all
	NULLIF($4 :: int, 0)
`

type GetTemplateVersionsByTemplateIDParams struct {
	TemplateID uuid.UUID `db:"template_id" json:"template_id"`
	AfterID    uuid.UUID `db:"after_id" json:"after_id"`
	OffsetOpt  int32     `db:"offset_opt" json:"offset_opt"`
	LimitOpt   int32     `db:"limit_opt" json:"limit_opt"`
}

func (q *sqlQuerier) GetTemplateVersionsByTemplateID(ctx context.Context, arg GetTemplateVersionsByTemplateIDParams) ([]TemplateVersion, error) {
	rows, err := q.db.QueryContext(ctx, getTemplateVersionsByTemplateID,
		arg.TemplateID,
		arg.AfterID,
		arg.OffsetOpt,
		arg.LimitOpt,
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []TemplateVersion
	for rows.Next() {
		var i TemplateVersion
		if err := rows.Scan(
			&i.ID,
			&i.TemplateID,
			&i.OrganizationID,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.Name,
			&i.Readme,
			&i.JobID,
			&i.CreatedBy,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getTemplateVersionsCreatedAfter = `-- name: GetTemplateVersionsCreatedAfter :many
SELECT id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by FROM template_versions WHERE created_at > $1
`

func (q *sqlQuerier) GetTemplateVersionsCreatedAfter(ctx context.Context, createdAt time.Time) ([]TemplateVersion, error) {
	rows, err := q.db.QueryContext(ctx, getTemplateVersionsCreatedAfter, createdAt)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []TemplateVersion
	for rows.Next() {
		var i TemplateVersion
		if err := rows.Scan(
			&i.ID,
			&i.TemplateID,
			&i.OrganizationID,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.Name,
			&i.Readme,
			&i.JobID,
			&i.CreatedBy,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const insertTemplateVersion = `-- name: InsertTemplateVersion :one
INSERT INTO
	template_versions (
		id,
		template_id,
		organization_id,
		created_at,
		updated_at,
		"name",
		readme,
		job_id,
		created_by
	)
VALUES
	($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by
`

type InsertTemplateVersionParams struct {
	ID             uuid.UUID     `db:"id" json:"id"`
	TemplateID     uuid.NullUUID `db:"template_id" json:"template_id"`
	OrganizationID uuid.UUID     `db:"organization_id" json:"organization_id"`
	CreatedAt      time.Time     `db:"created_at" json:"created_at"`
	UpdatedAt      time.Time     `db:"updated_at" json:"updated_at"`
	Name           string        `db:"name" json:"name"`
	Readme         string        `db:"readme" json:"readme"`
	JobID          uuid.UUID     `db:"job_id" json:"job_id"`
	CreatedBy      uuid.NullUUID `db:"created_by" json:"created_by"`
}

func (q *sqlQuerier) InsertTemplateVersion(ctx context.Context, arg InsertTemplateVersionParams) (TemplateVersion, error) {
	row := q.db.QueryRowContext(ctx, insertTemplateVersion,
		arg.ID,
		arg.TemplateID,
		arg.OrganizationID,
		arg.CreatedAt,
		arg.UpdatedAt,
		arg.Name,
		arg.Readme,
		arg.JobID,
		arg.CreatedBy,
	)
	var i TemplateVersion
	err := row.Scan(
		&i.ID,
		&i.TemplateID,
		&i.OrganizationID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Name,
		&i.Readme,
		&i.JobID,
		&i.CreatedBy,
	)
	return i, err
}

const updateTemplateVersionByID = `-- name: UpdateTemplateVersionByID :exec
UPDATE
	template_versions
SET
	template_id = $2,
	updated_at = $3
WHERE
	id = $1
`

type UpdateTemplateVersionByIDParams struct {
	ID         uuid.UUID     `db:"id" json:"id"`
	TemplateID uuid.NullUUID `db:"template_id" json:"template_id"`
	UpdatedAt  time.Time     `db:"updated_at" json:"updated_at"`
}

func (q *sqlQuerier) UpdateTemplateVersionByID(ctx context.Context, arg UpdateTemplateVersionByIDParams) error {
	_, err := q.db.ExecContext(ctx, updateTemplateVersionByID, arg.ID, arg.TemplateID, arg.UpdatedAt)
	return err
}

const updateTemplateVersionDescriptionByJobID = `-- name: UpdateTemplateVersionDescriptionByJobID :exec
UPDATE
	template_versions
SET
	readme = $2,
	updated_at = $3
WHERE
	job_id = $1
`

type UpdateTemplateVersionDescriptionByJobIDParams struct {
	JobID     uuid.UUID `db:"job_id" json:"job_id"`
	Readme    string    `db:"readme" json:"readme"`
	UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
}

func (q *sqlQuerier) UpdateTemplateVersionDescriptionByJobID(ctx context.Context, arg UpdateTemplateVersionDescriptionByJobIDParams) error {
	_, err := q.db.ExecContext(ctx, updateTemplateVersionDescriptionByJobID, arg.JobID, arg.Readme, arg.UpdatedAt)
	return err
}

const getUserLinkByLinkedID = `-- name: GetUserLinkByLinkedID :one
SELECT
	user_id, login_type, linked_id, oauth_access_token, oauth_refresh_token, oauth_expiry
FROM
	user_links
WHERE
	linked_id = $1
`

func (q *sqlQuerier) GetUserLinkByLinkedID(ctx context.Context, linkedID string) (UserLink, error) {
	row := q.db.QueryRowContext(ctx, getUserLinkByLinkedID, linkedID)
	var i UserLink
	err := row.Scan(
		&i.UserID,
		&i.LoginType,
		&i.LinkedID,
		&i.OAuthAccessToken,
		&i.OAuthRefreshToken,
		&i.OAuthExpiry,
	)
	return i, err
}

const getUserLinkByUserIDLoginType = `-- name: GetUserLinkByUserIDLoginType :one
SELECT
	user_id, login_type, linked_id, oauth_access_token, oauth_refresh_token, oauth_expiry
FROM
	user_links
WHERE
	user_id = $1 AND login_type = $2
`

type GetUserLinkByUserIDLoginTypeParams struct {
	UserID    uuid.UUID `db:"user_id" json:"user_id"`
	LoginType LoginType `db:"login_type" json:"login_type"`
}

func (q *sqlQuerier) GetUserLinkByUserIDLoginType(ctx context.Context, arg GetUserLinkByUserIDLoginTypeParams) (UserLink, error) {
	row := q.db.QueryRowContext(ctx, getUserLinkByUserIDLoginType, arg.UserID, arg.LoginType)
	var i UserLink
	err := row.Scan(
		&i.UserID,
		&i.LoginType,
		&i.LinkedID,
		&i.OAuthAccessToken,
		&i.OAuthRefreshToken,
		&i.OAuthExpiry,
	)
	return i, err
}

const insertUserLink = `-- name: InsertUserLink :one
INSERT INTO
	user_links (
		user_id,
		login_type,
		linked_id,
		oauth_access_token,
		oauth_refresh_token,
		oauth_expiry
	)
VALUES
	( $1, $2, $3, $4, $5, $6 ) RETURNING user_id, login_type, linked_id, oauth_access_token, oauth_refresh_token, oauth_expiry
`

type InsertUserLinkParams struct {
	UserID            uuid.UUID `db:"user_id" json:"user_id"`
	LoginType         LoginType `db:"login_type" json:"login_type"`
	LinkedID          string    `db:"linked_id" json:"linked_id"`
	OAuthAccessToken  string    `db:"oauth_access_token" json:"oauth_access_token"`
	OAuthRefreshToken string    `db:"oauth_refresh_token" json:"oauth_refresh_token"`
	OAuthExpiry       time.Time `db:"oauth_expiry" json:"oauth_expiry"`
}

func (q *sqlQuerier) InsertUserLink(ctx context.Context, arg InsertUserLinkParams) (UserLink, error) {
	row := q.db.QueryRowContext(ctx, insertUserLink,
		arg.UserID,
		arg.LoginType,
		arg.LinkedID,
		arg.OAuthAccessToken,
		arg.OAuthRefreshToken,
		arg.OAuthExpiry,
	)
	var i UserLink
	err := row.Scan(
		&i.UserID,
		&i.LoginType,
		&i.LinkedID,
		&i.OAuthAccessToken,
		&i.OAuthRefreshToken,
		&i.OAuthExpiry,
	)
	return i, err
}

const updateUserLink = `-- name: UpdateUserLink :one
UPDATE
	user_links
SET
	oauth_access_token = $1,
	oauth_refresh_token = $2,
	oauth_expiry = $3
WHERE
	user_id = $4 AND login_type = $5 RETURNING user_id, login_type, linked_id, oauth_access_token, oauth_refresh_token, oauth_expiry
`

type UpdateUserLinkParams struct {
	OAuthAccessToken  string    `db:"oauth_access_token" json:"oauth_access_token"`
	OAuthRefreshToken string    `db:"oauth_refresh_token" json:"oauth_refresh_token"`
	OAuthExpiry       time.Time `db:"oauth_expiry" json:"oauth_expiry"`
	UserID            uuid.UUID `db:"user_id" json:"user_id"`
	LoginType         LoginType `db:"login_type" json:"login_type"`
}

func (q *sqlQuerier) UpdateUserLink(ctx context.Context, arg UpdateUserLinkParams) (UserLink, error) {
	row := q.db.QueryRowContext(ctx, updateUserLink,
		arg.OAuthAccessToken,
		arg.OAuthRefreshToken,
		arg.OAuthExpiry,
		arg.UserID,
		arg.LoginType,
	)
	var i UserLink
	err := row.Scan(
		&i.UserID,
		&i.LoginType,
		&i.LinkedID,
		&i.OAuthAccessToken,
		&i.OAuthRefreshToken,
		&i.OAuthExpiry,
	)
	return i, err
}

const updateUserLinkedID = `-- name: UpdateUserLinkedID :one
UPDATE
	user_links
SET
	linked_id = $1
WHERE
	user_id = $2 AND login_type = $3 RETURNING user_id, login_type, linked_id, oauth_access_token, oauth_refresh_token, oauth_expiry
`

type UpdateUserLinkedIDParams struct {
	LinkedID  string    `db:"linked_id" json:"linked_id"`
	UserID    uuid.UUID `db:"user_id" json:"user_id"`
	LoginType LoginType `db:"login_type" json:"login_type"`
}

func (q *sqlQuerier) UpdateUserLinkedID(ctx context.Context, arg UpdateUserLinkedIDParams) (UserLink, error) {
	row := q.db.QueryRowContext(ctx, updateUserLinkedID, arg.LinkedID, arg.UserID, arg.LoginType)
	var i UserLink
	err := row.Scan(
		&i.UserID,
		&i.LoginType,
		&i.LinkedID,
		&i.OAuthAccessToken,
		&i.OAuthRefreshToken,
		&i.OAuthExpiry,
	)
	return i, err
}

const getAuthorizationUserRoles = `-- name: GetAuthorizationUserRoles :one
SELECT
	-- username is returned just to help for logging purposes
	-- status is used to enforce 'suspended' users, as all roles are ignored
	--	when suspended.
	id, username, status,
	array_cat(
		-- All users are members
			array_append(users.rbac_roles, 'member'),
		-- All org_members get the org-member role for their orgs
			array_append(organization_members.roles, 'organization-member:'||organization_members.organization_id::text)) :: text[]
		AS roles
FROM
	users
LEFT JOIN organization_members
	ON id = user_id
WHERE
	id = $1
`

type GetAuthorizationUserRolesRow struct {
	ID       uuid.UUID  `db:"id" json:"id"`
	Username string     `db:"username" json:"username"`
	Status   UserStatus `db:"status" json:"status"`
	Roles    []string   `db:"roles" json:"roles"`
}

// This function returns roles for authorization purposes. Implied member roles
// are included.
func (q *sqlQuerier) GetAuthorizationUserRoles(ctx context.Context, userID uuid.UUID) (GetAuthorizationUserRolesRow, error) {
	row := q.db.QueryRowContext(ctx, getAuthorizationUserRoles, userID)
	var i GetAuthorizationUserRolesRow
	err := row.Scan(
		&i.ID,
		&i.Username,
		&i.Status,
		pq.Array(&i.Roles),
	)
	return i, err
}

const getUserByEmailOrUsername = `-- name: GetUserByEmailOrUsername :one
SELECT
	id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type
FROM
	users
WHERE
	LOWER(username) = LOWER($1)
	OR email = $2
LIMIT
	1
`

type GetUserByEmailOrUsernameParams struct {
	Username string `db:"username" json:"username"`
	Email    string `db:"email" json:"email"`
}

func (q *sqlQuerier) GetUserByEmailOrUsername(ctx context.Context, arg GetUserByEmailOrUsernameParams) (User, error) {
	row := q.db.QueryRowContext(ctx, getUserByEmailOrUsername, arg.Username, arg.Email)
	var i User
	err := row.Scan(
		&i.ID,
		&i.Email,
		&i.Username,
		&i.HashedPassword,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Status,
		pq.Array(&i.RBACRoles),
		&i.LoginType,
	)
	return i, err
}

const getUserByID = `-- name: GetUserByID :one
SELECT
	id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type
FROM
	users
WHERE
	id = $1
LIMIT
	1
`

func (q *sqlQuerier) GetUserByID(ctx context.Context, id uuid.UUID) (User, error) {
	row := q.db.QueryRowContext(ctx, getUserByID, id)
	var i User
	err := row.Scan(
		&i.ID,
		&i.Email,
		&i.Username,
		&i.HashedPassword,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Status,
		pq.Array(&i.RBACRoles),
		&i.LoginType,
	)
	return i, err
}

const getUserCount = `-- name: GetUserCount :one
SELECT
	COUNT(*)
FROM
	users
`

func (q *sqlQuerier) GetUserCount(ctx context.Context) (int64, error) {
	row := q.db.QueryRowContext(ctx, getUserCount)
	var count int64
	err := row.Scan(&count)
	return count, err
}

const getUsers = `-- name: GetUsers :many
SELECT
	id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type
FROM
	users
WHERE
	CASE
		-- This allows using the last element on a page as effectively a cursor.
		-- This is an important option for scripts that need to paginate without
		-- duplicating or missing data.
		WHEN $1 :: uuid != '00000000-00000000-00000000-00000000' THEN (
			-- The pagination cursor is the last ID of the previous page.
			-- The query is ordered by the created_at field, so select all
			-- rows after the cursor.
			(created_at, id) > (
				SELECT
					created_at, id
				FROM
					users
				WHERE
					id = $1
			)
		)
		ELSE true
	END
	-- Start filters
	-- Filter by name, email or username
	AND CASE
		WHEN $2 :: text != '' THEN (
			email ILIKE concat('%', $2, '%')
			OR username ILIKE concat('%', $2, '%')
		)
		ELSE true
	END
	-- Filter by status
	AND CASE
		-- @status needs to be a text because it can be empty, If it was
		-- user_status enum, it would not.
		WHEN cardinality($3 :: user_status[]) > 0 THEN
			status = ANY($3 :: user_status[])
		ELSE true
	END
	-- Filter by rbac_roles
	AND CASE
		-- @rbac_role allows filtering by rbac roles. If 'member' is included, show everyone, as
	    -- everyone is a member.
		WHEN cardinality($4 :: text[]) > 0 AND 'member' != ANY($4 :: text[]) THEN
		    rbac_roles && $4 :: text[]
		ELSE true
	END
	-- End of filters
ORDER BY
	-- Deterministic and consistent ordering of all users, even if they share
	-- a timestamp. This is to ensure consistent pagination.
	(created_at, id) ASC OFFSET $5
LIMIT
	-- A null limit means "no limit", so 0 means return all
	NULLIF($6 :: int, 0)
`

type GetUsersParams struct {
	AfterID   uuid.UUID    `db:"after_id" json:"after_id"`
	Search    string       `db:"search" json:"search"`
	Status    []UserStatus `db:"status" json:"status"`
	RbacRole  []string     `db:"rbac_role" json:"rbac_role"`
	OffsetOpt int32        `db:"offset_opt" json:"offset_opt"`
	LimitOpt  int32        `db:"limit_opt" json:"limit_opt"`
}

func (q *sqlQuerier) GetUsers(ctx context.Context, arg GetUsersParams) ([]User, error) {
	rows, err := q.db.QueryContext(ctx, getUsers,
		arg.AfterID,
		arg.Search,
		pq.Array(arg.Status),
		pq.Array(arg.RbacRole),
		arg.OffsetOpt,
		arg.LimitOpt,
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []User
	for rows.Next() {
		var i User
		if err := rows.Scan(
			&i.ID,
			&i.Email,
			&i.Username,
			&i.HashedPassword,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.Status,
			pq.Array(&i.RBACRoles),
			&i.LoginType,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getUsersByIDs = `-- name: GetUsersByIDs :many
SELECT id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type FROM users WHERE id = ANY($1 :: uuid [ ])
`

func (q *sqlQuerier) GetUsersByIDs(ctx context.Context, ids []uuid.UUID) ([]User, error) {
	rows, err := q.db.QueryContext(ctx, getUsersByIDs, pq.Array(ids))
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []User
	for rows.Next() {
		var i User
		if err := rows.Scan(
			&i.ID,
			&i.Email,
			&i.Username,
			&i.HashedPassword,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.Status,
			pq.Array(&i.RBACRoles),
			&i.LoginType,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const insertUser = `-- name: InsertUser :one
INSERT INTO
	users (
		id,
		email,
		username,
		hashed_password,
		created_at,
		updated_at,
		rbac_roles,
		login_type
	)
VALUES
	($1, $2, $3, $4, $5, $6, $7, $8) RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type
`

type InsertUserParams struct {
	ID             uuid.UUID `db:"id" json:"id"`
	Email          string    `db:"email" json:"email"`
	Username       string    `db:"username" json:"username"`
	HashedPassword []byte    `db:"hashed_password" json:"hashed_password"`
	CreatedAt      time.Time `db:"created_at" json:"created_at"`
	UpdatedAt      time.Time `db:"updated_at" json:"updated_at"`
	RBACRoles      []string  `db:"rbac_roles" json:"rbac_roles"`
	LoginType      LoginType `db:"login_type" json:"login_type"`
}

func (q *sqlQuerier) InsertUser(ctx context.Context, arg InsertUserParams) (User, error) {
	row := q.db.QueryRowContext(ctx, insertUser,
		arg.ID,
		arg.Email,
		arg.Username,
		arg.HashedPassword,
		arg.CreatedAt,
		arg.UpdatedAt,
		pq.Array(arg.RBACRoles),
		arg.LoginType,
	)
	var i User
	err := row.Scan(
		&i.ID,
		&i.Email,
		&i.Username,
		&i.HashedPassword,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Status,
		pq.Array(&i.RBACRoles),
		&i.LoginType,
	)
	return i, err
}

const updateUserHashedPassword = `-- name: UpdateUserHashedPassword :exec
UPDATE
	users
SET
	hashed_password = $2
WHERE
	id = $1
`

type UpdateUserHashedPasswordParams struct {
	ID             uuid.UUID `db:"id" json:"id"`
	HashedPassword []byte    `db:"hashed_password" json:"hashed_password"`
}

func (q *sqlQuerier) UpdateUserHashedPassword(ctx context.Context, arg UpdateUserHashedPasswordParams) error {
	_, err := q.db.ExecContext(ctx, updateUserHashedPassword, arg.ID, arg.HashedPassword)
	return err
}

const updateUserProfile = `-- name: UpdateUserProfile :one
UPDATE
	users
SET
	email = $2,
	username = $3,
	updated_at = $4
WHERE
	id = $1 RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type
`

type UpdateUserProfileParams struct {
	ID        uuid.UUID `db:"id" json:"id"`
	Email     string    `db:"email" json:"email"`
	Username  string    `db:"username" json:"username"`
	UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
}

func (q *sqlQuerier) UpdateUserProfile(ctx context.Context, arg UpdateUserProfileParams) (User, error) {
	row := q.db.QueryRowContext(ctx, updateUserProfile,
		arg.ID,
		arg.Email,
		arg.Username,
		arg.UpdatedAt,
	)
	var i User
	err := row.Scan(
		&i.ID,
		&i.Email,
		&i.Username,
		&i.HashedPassword,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Status,
		pq.Array(&i.RBACRoles),
		&i.LoginType,
	)
	return i, err
}

const updateUserRoles = `-- name: UpdateUserRoles :one
UPDATE
	users
SET
	-- Remove all duplicates from the roles.
	rbac_roles = ARRAY(SELECT DISTINCT UNNEST($1 :: text[]))
WHERE
	id = $2
RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type
`

type UpdateUserRolesParams struct {
	GrantedRoles []string  `db:"granted_roles" json:"granted_roles"`
	ID           uuid.UUID `db:"id" json:"id"`
}

func (q *sqlQuerier) UpdateUserRoles(ctx context.Context, arg UpdateUserRolesParams) (User, error) {
	row := q.db.QueryRowContext(ctx, updateUserRoles, pq.Array(arg.GrantedRoles), arg.ID)
	var i User
	err := row.Scan(
		&i.ID,
		&i.Email,
		&i.Username,
		&i.HashedPassword,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Status,
		pq.Array(&i.RBACRoles),
		&i.LoginType,
	)
	return i, err
}

const updateUserStatus = `-- name: UpdateUserStatus :one
UPDATE
	users
SET
	status = $2,
	updated_at = $3
WHERE
	id = $1 RETURNING id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type
`

type UpdateUserStatusParams struct {
	ID        uuid.UUID  `db:"id" json:"id"`
	Status    UserStatus `db:"status" json:"status"`
	UpdatedAt time.Time  `db:"updated_at" json:"updated_at"`
}

func (q *sqlQuerier) UpdateUserStatus(ctx context.Context, arg UpdateUserStatusParams) (User, error) {
	row := q.db.QueryRowContext(ctx, updateUserStatus, arg.ID, arg.Status, arg.UpdatedAt)
	var i User
	err := row.Scan(
		&i.ID,
		&i.Email,
		&i.Username,
		&i.HashedPassword,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Status,
		pq.Array(&i.RBACRoles),
		&i.LoginType,
	)
	return i, err
}

const getWorkspaceAgentByAuthToken = `-- name: GetWorkspaceAgentByAuthToken :one
SELECT
	id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, wireguard_node_ipv6, wireguard_node_public_key, wireguard_disco_public_key
FROM
	workspace_agents
WHERE
	auth_token = $1
ORDER BY
	created_at DESC
`

func (q *sqlQuerier) GetWorkspaceAgentByAuthToken(ctx context.Context, authToken uuid.UUID) (WorkspaceAgent, error) {
	row := q.db.QueryRowContext(ctx, getWorkspaceAgentByAuthToken, authToken)
	var i WorkspaceAgent
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Name,
		&i.FirstConnectedAt,
		&i.LastConnectedAt,
		&i.DisconnectedAt,
		&i.ResourceID,
		&i.AuthToken,
		&i.AuthInstanceID,
		&i.Architecture,
		&i.EnvironmentVariables,
		&i.OperatingSystem,
		&i.StartupScript,
		&i.InstanceMetadata,
		&i.ResourceMetadata,
		&i.Directory,
		&i.WireguardNodeIPv6,
		&i.WireguardNodePublicKey,
		&i.WireguardDiscoPublicKey,
	)
	return i, err
}

const getWorkspaceAgentByID = `-- name: GetWorkspaceAgentByID :one
SELECT
	id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, wireguard_node_ipv6, wireguard_node_public_key, wireguard_disco_public_key
FROM
	workspace_agents
WHERE
	id = $1
`

func (q *sqlQuerier) GetWorkspaceAgentByID(ctx context.Context, id uuid.UUID) (WorkspaceAgent, error) {
	row := q.db.QueryRowContext(ctx, getWorkspaceAgentByID, id)
	var i WorkspaceAgent
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Name,
		&i.FirstConnectedAt,
		&i.LastConnectedAt,
		&i.DisconnectedAt,
		&i.ResourceID,
		&i.AuthToken,
		&i.AuthInstanceID,
		&i.Architecture,
		&i.EnvironmentVariables,
		&i.OperatingSystem,
		&i.StartupScript,
		&i.InstanceMetadata,
		&i.ResourceMetadata,
		&i.Directory,
		&i.WireguardNodeIPv6,
		&i.WireguardNodePublicKey,
		&i.WireguardDiscoPublicKey,
	)
	return i, err
}

const getWorkspaceAgentByInstanceID = `-- name: GetWorkspaceAgentByInstanceID :one
SELECT
	id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, wireguard_node_ipv6, wireguard_node_public_key, wireguard_disco_public_key
FROM
	workspace_agents
WHERE
	auth_instance_id = $1 :: TEXT
ORDER BY
	created_at DESC
`

func (q *sqlQuerier) GetWorkspaceAgentByInstanceID(ctx context.Context, authInstanceID string) (WorkspaceAgent, error) {
	row := q.db.QueryRowContext(ctx, getWorkspaceAgentByInstanceID, authInstanceID)
	var i WorkspaceAgent
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Name,
		&i.FirstConnectedAt,
		&i.LastConnectedAt,
		&i.DisconnectedAt,
		&i.ResourceID,
		&i.AuthToken,
		&i.AuthInstanceID,
		&i.Architecture,
		&i.EnvironmentVariables,
		&i.OperatingSystem,
		&i.StartupScript,
		&i.InstanceMetadata,
		&i.ResourceMetadata,
		&i.Directory,
		&i.WireguardNodeIPv6,
		&i.WireguardNodePublicKey,
		&i.WireguardDiscoPublicKey,
	)
	return i, err
}

const getWorkspaceAgentsByResourceIDs = `-- name: GetWorkspaceAgentsByResourceIDs :many
SELECT
	id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, wireguard_node_ipv6, wireguard_node_public_key, wireguard_disco_public_key
FROM
	workspace_agents
WHERE
	resource_id = ANY($1 :: uuid [ ])
`

func (q *sqlQuerier) GetWorkspaceAgentsByResourceIDs(ctx context.Context, ids []uuid.UUID) ([]WorkspaceAgent, error) {
	rows, err := q.db.QueryContext(ctx, getWorkspaceAgentsByResourceIDs, pq.Array(ids))
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []WorkspaceAgent
	for rows.Next() {
		var i WorkspaceAgent
		if err := rows.Scan(
			&i.ID,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.Name,
			&i.FirstConnectedAt,
			&i.LastConnectedAt,
			&i.DisconnectedAt,
			&i.ResourceID,
			&i.AuthToken,
			&i.AuthInstanceID,
			&i.Architecture,
			&i.EnvironmentVariables,
			&i.OperatingSystem,
			&i.StartupScript,
			&i.InstanceMetadata,
			&i.ResourceMetadata,
			&i.Directory,
			&i.WireguardNodeIPv6,
			&i.WireguardNodePublicKey,
			&i.WireguardDiscoPublicKey,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getWorkspaceAgentsCreatedAfter = `-- name: GetWorkspaceAgentsCreatedAfter :many
SELECT id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, wireguard_node_ipv6, wireguard_node_public_key, wireguard_disco_public_key FROM workspace_agents WHERE created_at > $1
`

func (q *sqlQuerier) GetWorkspaceAgentsCreatedAfter(ctx context.Context, createdAt time.Time) ([]WorkspaceAgent, error) {
	rows, err := q.db.QueryContext(ctx, getWorkspaceAgentsCreatedAfter, createdAt)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []WorkspaceAgent
	for rows.Next() {
		var i WorkspaceAgent
		if err := rows.Scan(
			&i.ID,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.Name,
			&i.FirstConnectedAt,
			&i.LastConnectedAt,
			&i.DisconnectedAt,
			&i.ResourceID,
			&i.AuthToken,
			&i.AuthInstanceID,
			&i.Architecture,
			&i.EnvironmentVariables,
			&i.OperatingSystem,
			&i.StartupScript,
			&i.InstanceMetadata,
			&i.ResourceMetadata,
			&i.Directory,
			&i.WireguardNodeIPv6,
			&i.WireguardNodePublicKey,
			&i.WireguardDiscoPublicKey,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const insertWorkspaceAgent = `-- name: InsertWorkspaceAgent :one
INSERT INTO
	workspace_agents (
		id,
		created_at,
		updated_at,
		name,
		resource_id,
		auth_token,
		auth_instance_id,
		architecture,
		environment_variables,
		operating_system,
		startup_script,
		directory,
		instance_metadata,
		resource_metadata,
		wireguard_node_ipv6,
		wireguard_node_public_key,
		wireguard_disco_public_key
	)
VALUES
	($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17) RETURNING id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, wireguard_node_ipv6, wireguard_node_public_key, wireguard_disco_public_key
`

type InsertWorkspaceAgentParams struct {
	ID                      uuid.UUID             `db:"id" json:"id"`
	CreatedAt               time.Time             `db:"created_at" json:"created_at"`
	UpdatedAt               time.Time             `db:"updated_at" json:"updated_at"`
	Name                    string                `db:"name" json:"name"`
	ResourceID              uuid.UUID             `db:"resource_id" json:"resource_id"`
	AuthToken               uuid.UUID             `db:"auth_token" json:"auth_token"`
	AuthInstanceID          sql.NullString        `db:"auth_instance_id" json:"auth_instance_id"`
	Architecture            string                `db:"architecture" json:"architecture"`
	EnvironmentVariables    pqtype.NullRawMessage `db:"environment_variables" json:"environment_variables"`
	OperatingSystem         string                `db:"operating_system" json:"operating_system"`
	StartupScript           sql.NullString        `db:"startup_script" json:"startup_script"`
	Directory               string                `db:"directory" json:"directory"`
	InstanceMetadata        pqtype.NullRawMessage `db:"instance_metadata" json:"instance_metadata"`
	ResourceMetadata        pqtype.NullRawMessage `db:"resource_metadata" json:"resource_metadata"`
	WireguardNodeIPv6       pqtype.Inet           `db:"wireguard_node_ipv6" json:"wireguard_node_ipv6"`
	WireguardNodePublicKey  dbtypes.NodePublic    `db:"wireguard_node_public_key" json:"wireguard_node_public_key"`
	WireguardDiscoPublicKey dbtypes.DiscoPublic   `db:"wireguard_disco_public_key" json:"wireguard_disco_public_key"`
}

func (q *sqlQuerier) InsertWorkspaceAgent(ctx context.Context, arg InsertWorkspaceAgentParams) (WorkspaceAgent, error) {
	row := q.db.QueryRowContext(ctx, insertWorkspaceAgent,
		arg.ID,
		arg.CreatedAt,
		arg.UpdatedAt,
		arg.Name,
		arg.ResourceID,
		arg.AuthToken,
		arg.AuthInstanceID,
		arg.Architecture,
		arg.EnvironmentVariables,
		arg.OperatingSystem,
		arg.StartupScript,
		arg.Directory,
		arg.InstanceMetadata,
		arg.ResourceMetadata,
		arg.WireguardNodeIPv6,
		arg.WireguardNodePublicKey,
		arg.WireguardDiscoPublicKey,
	)
	var i WorkspaceAgent
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Name,
		&i.FirstConnectedAt,
		&i.LastConnectedAt,
		&i.DisconnectedAt,
		&i.ResourceID,
		&i.AuthToken,
		&i.AuthInstanceID,
		&i.Architecture,
		&i.EnvironmentVariables,
		&i.OperatingSystem,
		&i.StartupScript,
		&i.InstanceMetadata,
		&i.ResourceMetadata,
		&i.Directory,
		&i.WireguardNodeIPv6,
		&i.WireguardNodePublicKey,
		&i.WireguardDiscoPublicKey,
	)
	return i, err
}

const updateWorkspaceAgentConnectionByID = `-- name: UpdateWorkspaceAgentConnectionByID :exec
UPDATE
	workspace_agents
SET
	first_connected_at = $2,
	last_connected_at = $3,
	disconnected_at = $4,
	updated_at = $5
WHERE
	id = $1
`

type UpdateWorkspaceAgentConnectionByIDParams struct {
	ID               uuid.UUID    `db:"id" json:"id"`
	FirstConnectedAt sql.NullTime `db:"first_connected_at" json:"first_connected_at"`
	LastConnectedAt  sql.NullTime `db:"last_connected_at" json:"last_connected_at"`
	DisconnectedAt   sql.NullTime `db:"disconnected_at" json:"disconnected_at"`
	UpdatedAt        time.Time    `db:"updated_at" json:"updated_at"`
}

func (q *sqlQuerier) UpdateWorkspaceAgentConnectionByID(ctx context.Context, arg UpdateWorkspaceAgentConnectionByIDParams) error {
	_, err := q.db.ExecContext(ctx, updateWorkspaceAgentConnectionByID,
		arg.ID,
		arg.FirstConnectedAt,
		arg.LastConnectedAt,
		arg.DisconnectedAt,
		arg.UpdatedAt,
	)
	return err
}

const updateWorkspaceAgentKeysByID = `-- name: UpdateWorkspaceAgentKeysByID :exec
UPDATE
	workspace_agents
SET
	wireguard_node_public_key = $2,
	wireguard_disco_public_key = $3,
	updated_at = $4
WHERE
	id = $1
`

type UpdateWorkspaceAgentKeysByIDParams struct {
	ID                      uuid.UUID           `db:"id" json:"id"`
	WireguardNodePublicKey  dbtypes.NodePublic  `db:"wireguard_node_public_key" json:"wireguard_node_public_key"`
	WireguardDiscoPublicKey dbtypes.DiscoPublic `db:"wireguard_disco_public_key" json:"wireguard_disco_public_key"`
	UpdatedAt               time.Time           `db:"updated_at" json:"updated_at"`
}

func (q *sqlQuerier) UpdateWorkspaceAgentKeysByID(ctx context.Context, arg UpdateWorkspaceAgentKeysByIDParams) error {
	_, err := q.db.ExecContext(ctx, updateWorkspaceAgentKeysByID,
		arg.ID,
		arg.WireguardNodePublicKey,
		arg.WireguardDiscoPublicKey,
		arg.UpdatedAt,
	)
	return err
}

const getWorkspaceAppByAgentIDAndName = `-- name: GetWorkspaceAppByAgentIDAndName :one
SELECT id, created_at, agent_id, name, icon, command, url, relative_path FROM workspace_apps WHERE agent_id = $1 AND name = $2
`

type GetWorkspaceAppByAgentIDAndNameParams struct {
	AgentID uuid.UUID `db:"agent_id" json:"agent_id"`
	Name    string    `db:"name" json:"name"`
}

func (q *sqlQuerier) GetWorkspaceAppByAgentIDAndName(ctx context.Context, arg GetWorkspaceAppByAgentIDAndNameParams) (WorkspaceApp, error) {
	row := q.db.QueryRowContext(ctx, getWorkspaceAppByAgentIDAndName, arg.AgentID, arg.Name)
	var i WorkspaceApp
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.AgentID,
		&i.Name,
		&i.Icon,
		&i.Command,
		&i.Url,
		&i.RelativePath,
	)
	return i, err
}

const getWorkspaceAppsByAgentID = `-- name: GetWorkspaceAppsByAgentID :many
SELECT id, created_at, agent_id, name, icon, command, url, relative_path FROM workspace_apps WHERE agent_id = $1 ORDER BY name ASC
`

func (q *sqlQuerier) GetWorkspaceAppsByAgentID(ctx context.Context, agentID uuid.UUID) ([]WorkspaceApp, error) {
	rows, err := q.db.QueryContext(ctx, getWorkspaceAppsByAgentID, agentID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []WorkspaceApp
	for rows.Next() {
		var i WorkspaceApp
		if err := rows.Scan(
			&i.ID,
			&i.CreatedAt,
			&i.AgentID,
			&i.Name,
			&i.Icon,
			&i.Command,
			&i.Url,
			&i.RelativePath,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getWorkspaceAppsByAgentIDs = `-- name: GetWorkspaceAppsByAgentIDs :many
SELECT id, created_at, agent_id, name, icon, command, url, relative_path FROM workspace_apps WHERE agent_id = ANY($1 :: uuid [ ]) ORDER BY name ASC
`

func (q *sqlQuerier) GetWorkspaceAppsByAgentIDs(ctx context.Context, ids []uuid.UUID) ([]WorkspaceApp, error) {
	rows, err := q.db.QueryContext(ctx, getWorkspaceAppsByAgentIDs, pq.Array(ids))
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []WorkspaceApp
	for rows.Next() {
		var i WorkspaceApp
		if err := rows.Scan(
			&i.ID,
			&i.CreatedAt,
			&i.AgentID,
			&i.Name,
			&i.Icon,
			&i.Command,
			&i.Url,
			&i.RelativePath,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getWorkspaceAppsCreatedAfter = `-- name: GetWorkspaceAppsCreatedAfter :many
SELECT id, created_at, agent_id, name, icon, command, url, relative_path FROM workspace_apps WHERE created_at > $1 ORDER BY name ASC
`

func (q *sqlQuerier) GetWorkspaceAppsCreatedAfter(ctx context.Context, createdAt time.Time) ([]WorkspaceApp, error) {
	rows, err := q.db.QueryContext(ctx, getWorkspaceAppsCreatedAfter, createdAt)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []WorkspaceApp
	for rows.Next() {
		var i WorkspaceApp
		if err := rows.Scan(
			&i.ID,
			&i.CreatedAt,
			&i.AgentID,
			&i.Name,
			&i.Icon,
			&i.Command,
			&i.Url,
			&i.RelativePath,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const insertWorkspaceApp = `-- name: InsertWorkspaceApp :one
INSERT INTO
    workspace_apps (
        id,
        created_at,
        agent_id,
        name,
        icon,
        command,
        url,
        relative_path
    )
VALUES
    ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING id, created_at, agent_id, name, icon, command, url, relative_path
`

type InsertWorkspaceAppParams struct {
	ID           uuid.UUID      `db:"id" json:"id"`
	CreatedAt    time.Time      `db:"created_at" json:"created_at"`
	AgentID      uuid.UUID      `db:"agent_id" json:"agent_id"`
	Name         string         `db:"name" json:"name"`
	Icon         string         `db:"icon" json:"icon"`
	Command      sql.NullString `db:"command" json:"command"`
	Url          sql.NullString `db:"url" json:"url"`
	RelativePath bool           `db:"relative_path" json:"relative_path"`
}

func (q *sqlQuerier) InsertWorkspaceApp(ctx context.Context, arg InsertWorkspaceAppParams) (WorkspaceApp, error) {
	row := q.db.QueryRowContext(ctx, insertWorkspaceApp,
		arg.ID,
		arg.CreatedAt,
		arg.AgentID,
		arg.Name,
		arg.Icon,
		arg.Command,
		arg.Url,
		arg.RelativePath,
	)
	var i WorkspaceApp
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.AgentID,
		&i.Name,
		&i.Icon,
		&i.Command,
		&i.Url,
		&i.RelativePath,
	)
	return i, err
}

const getLatestWorkspaceBuildByWorkspaceID = `-- name: GetLatestWorkspaceBuildByWorkspaceID :one
SELECT
	id, created_at, updated_at, workspace_id, template_version_id, name, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason
FROM
	workspace_builds
WHERE
	workspace_id = $1
ORDER BY
    build_number desc
LIMIT
	1
`

func (q *sqlQuerier) GetLatestWorkspaceBuildByWorkspaceID(ctx context.Context, workspaceID uuid.UUID) (WorkspaceBuild, error) {
	row := q.db.QueryRowContext(ctx, getLatestWorkspaceBuildByWorkspaceID, workspaceID)
	var i WorkspaceBuild
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.WorkspaceID,
		&i.TemplateVersionID,
		&i.Name,
		&i.BuildNumber,
		&i.Transition,
		&i.InitiatorID,
		&i.ProvisionerState,
		&i.JobID,
		&i.Deadline,
		&i.Reason,
	)
	return i, err
}

const getLatestWorkspaceBuilds = `-- name: GetLatestWorkspaceBuilds :many
SELECT wb.id, wb.created_at, wb.updated_at, wb.workspace_id, wb.template_version_id, wb.name, wb.build_number, wb.transition, wb.initiator_id, wb.provisioner_state, wb.job_id, wb.deadline, wb.reason
FROM (
    SELECT
        workspace_id, MAX(build_number) as max_build_number
    FROM
        workspace_builds
    GROUP BY
        workspace_id
) m
JOIN
    workspace_builds wb
ON m.workspace_id = wb.workspace_id AND m.max_build_number = wb.build_number
`

func (q *sqlQuerier) GetLatestWorkspaceBuilds(ctx context.Context) ([]WorkspaceBuild, error) {
	rows, err := q.db.QueryContext(ctx, getLatestWorkspaceBuilds)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []WorkspaceBuild
	for rows.Next() {
		var i WorkspaceBuild
		if err := rows.Scan(
			&i.ID,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.WorkspaceID,
			&i.TemplateVersionID,
			&i.Name,
			&i.BuildNumber,
			&i.Transition,
			&i.InitiatorID,
			&i.ProvisionerState,
			&i.JobID,
			&i.Deadline,
			&i.Reason,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getLatestWorkspaceBuildsByWorkspaceIDs = `-- name: GetLatestWorkspaceBuildsByWorkspaceIDs :many
SELECT wb.id, wb.created_at, wb.updated_at, wb.workspace_id, wb.template_version_id, wb.name, wb.build_number, wb.transition, wb.initiator_id, wb.provisioner_state, wb.job_id, wb.deadline, wb.reason
FROM (
    SELECT
        workspace_id, MAX(build_number) as max_build_number
    FROM
        workspace_builds
    WHERE
        workspace_id = ANY($1 :: uuid [ ])
    GROUP BY
        workspace_id
) m
JOIN
    workspace_builds wb
ON m.workspace_id = wb.workspace_id AND m.max_build_number = wb.build_number
`

func (q *sqlQuerier) GetLatestWorkspaceBuildsByWorkspaceIDs(ctx context.Context, ids []uuid.UUID) ([]WorkspaceBuild, error) {
	rows, err := q.db.QueryContext(ctx, getLatestWorkspaceBuildsByWorkspaceIDs, pq.Array(ids))
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []WorkspaceBuild
	for rows.Next() {
		var i WorkspaceBuild
		if err := rows.Scan(
			&i.ID,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.WorkspaceID,
			&i.TemplateVersionID,
			&i.Name,
			&i.BuildNumber,
			&i.Transition,
			&i.InitiatorID,
			&i.ProvisionerState,
			&i.JobID,
			&i.Deadline,
			&i.Reason,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getWorkspaceBuildByID = `-- name: GetWorkspaceBuildByID :one
SELECT
	id, created_at, updated_at, workspace_id, template_version_id, name, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason
FROM
	workspace_builds
WHERE
	id = $1
LIMIT
	1
`

func (q *sqlQuerier) GetWorkspaceBuildByID(ctx context.Context, id uuid.UUID) (WorkspaceBuild, error) {
	row := q.db.QueryRowContext(ctx, getWorkspaceBuildByID, id)
	var i WorkspaceBuild
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.WorkspaceID,
		&i.TemplateVersionID,
		&i.Name,
		&i.BuildNumber,
		&i.Transition,
		&i.InitiatorID,
		&i.ProvisionerState,
		&i.JobID,
		&i.Deadline,
		&i.Reason,
	)
	return i, err
}

const getWorkspaceBuildByJobID = `-- name: GetWorkspaceBuildByJobID :one
SELECT
	id, created_at, updated_at, workspace_id, template_version_id, name, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason
FROM
	workspace_builds
WHERE
	job_id = $1
LIMIT
	1
`

func (q *sqlQuerier) GetWorkspaceBuildByJobID(ctx context.Context, jobID uuid.UUID) (WorkspaceBuild, error) {
	row := q.db.QueryRowContext(ctx, getWorkspaceBuildByJobID, jobID)
	var i WorkspaceBuild
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.WorkspaceID,
		&i.TemplateVersionID,
		&i.Name,
		&i.BuildNumber,
		&i.Transition,
		&i.InitiatorID,
		&i.ProvisionerState,
		&i.JobID,
		&i.Deadline,
		&i.Reason,
	)
	return i, err
}

const getWorkspaceBuildByWorkspaceID = `-- name: GetWorkspaceBuildByWorkspaceID :many
SELECT
	id, created_at, updated_at, workspace_id, template_version_id, name, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason
FROM
	workspace_builds
WHERE
	workspace_builds.workspace_id = $1
    AND CASE
		-- This allows using the last element on a page as effectively a cursor.
		-- This is an important option for scripts that need to paginate without
		-- duplicating or missing data.
		WHEN $2 :: uuid != '00000000-00000000-00000000-00000000' THEN (
			-- The pagination cursor is the last ID of the previous page.
			-- The query is ordered by the build_number field, so select all
			-- rows after the cursor.
			build_number > (
				SELECT
					build_number
				FROM
					workspace_builds
				WHERE
					id = $2
			)
		)
		ELSE true
END
ORDER BY
    build_number desc OFFSET $3
LIMIT
    -- A null limit means "no limit", so 0 means return all
    NULLIF($4 :: int, 0)
`

type GetWorkspaceBuildByWorkspaceIDParams struct {
	WorkspaceID uuid.UUID `db:"workspace_id" json:"workspace_id"`
	AfterID     uuid.UUID `db:"after_id" json:"after_id"`
	OffsetOpt   int32     `db:"offset_opt" json:"offset_opt"`
	LimitOpt    int32     `db:"limit_opt" json:"limit_opt"`
}

func (q *sqlQuerier) GetWorkspaceBuildByWorkspaceID(ctx context.Context, arg GetWorkspaceBuildByWorkspaceIDParams) ([]WorkspaceBuild, error) {
	rows, err := q.db.QueryContext(ctx, getWorkspaceBuildByWorkspaceID,
		arg.WorkspaceID,
		arg.AfterID,
		arg.OffsetOpt,
		arg.LimitOpt,
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []WorkspaceBuild
	for rows.Next() {
		var i WorkspaceBuild
		if err := rows.Scan(
			&i.ID,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.WorkspaceID,
			&i.TemplateVersionID,
			&i.Name,
			&i.BuildNumber,
			&i.Transition,
			&i.InitiatorID,
			&i.ProvisionerState,
			&i.JobID,
			&i.Deadline,
			&i.Reason,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getWorkspaceBuildByWorkspaceIDAndBuildNumber = `-- name: GetWorkspaceBuildByWorkspaceIDAndBuildNumber :one
SELECT
	id, created_at, updated_at, workspace_id, template_version_id, name, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason
FROM
	workspace_builds
WHERE
	workspace_id = $1
	AND build_number = $2
`

type GetWorkspaceBuildByWorkspaceIDAndBuildNumberParams struct {
	WorkspaceID uuid.UUID `db:"workspace_id" json:"workspace_id"`
	BuildNumber int32     `db:"build_number" json:"build_number"`
}

func (q *sqlQuerier) GetWorkspaceBuildByWorkspaceIDAndBuildNumber(ctx context.Context, arg GetWorkspaceBuildByWorkspaceIDAndBuildNumberParams) (WorkspaceBuild, error) {
	row := q.db.QueryRowContext(ctx, getWorkspaceBuildByWorkspaceIDAndBuildNumber, arg.WorkspaceID, arg.BuildNumber)
	var i WorkspaceBuild
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.WorkspaceID,
		&i.TemplateVersionID,
		&i.Name,
		&i.BuildNumber,
		&i.Transition,
		&i.InitiatorID,
		&i.ProvisionerState,
		&i.JobID,
		&i.Deadline,
		&i.Reason,
	)
	return i, err
}

const getWorkspaceBuildByWorkspaceIDAndName = `-- name: GetWorkspaceBuildByWorkspaceIDAndName :one
SELECT
	id, created_at, updated_at, workspace_id, template_version_id, name, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason
FROM
	workspace_builds
WHERE
	workspace_id = $1
	AND "name" = $2
`

type GetWorkspaceBuildByWorkspaceIDAndNameParams struct {
	WorkspaceID uuid.UUID `db:"workspace_id" json:"workspace_id"`
	Name        string    `db:"name" json:"name"`
}

func (q *sqlQuerier) GetWorkspaceBuildByWorkspaceIDAndName(ctx context.Context, arg GetWorkspaceBuildByWorkspaceIDAndNameParams) (WorkspaceBuild, error) {
	row := q.db.QueryRowContext(ctx, getWorkspaceBuildByWorkspaceIDAndName, arg.WorkspaceID, arg.Name)
	var i WorkspaceBuild
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.WorkspaceID,
		&i.TemplateVersionID,
		&i.Name,
		&i.BuildNumber,
		&i.Transition,
		&i.InitiatorID,
		&i.ProvisionerState,
		&i.JobID,
		&i.Deadline,
		&i.Reason,
	)
	return i, err
}

const getWorkspaceBuildsCreatedAfter = `-- name: GetWorkspaceBuildsCreatedAfter :many
SELECT id, created_at, updated_at, workspace_id, template_version_id, name, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason FROM workspace_builds WHERE created_at > $1
`

func (q *sqlQuerier) GetWorkspaceBuildsCreatedAfter(ctx context.Context, createdAt time.Time) ([]WorkspaceBuild, error) {
	rows, err := q.db.QueryContext(ctx, getWorkspaceBuildsCreatedAfter, createdAt)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []WorkspaceBuild
	for rows.Next() {
		var i WorkspaceBuild
		if err := rows.Scan(
			&i.ID,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.WorkspaceID,
			&i.TemplateVersionID,
			&i.Name,
			&i.BuildNumber,
			&i.Transition,
			&i.InitiatorID,
			&i.ProvisionerState,
			&i.JobID,
			&i.Deadline,
			&i.Reason,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const insertWorkspaceBuild = `-- name: InsertWorkspaceBuild :one
INSERT INTO
	workspace_builds (
		id,
		created_at,
		updated_at,
		workspace_id,
		template_version_id,
		"build_number",
		"name",
		transition,
		initiator_id,
		job_id,
		provisioner_state,
		deadline,
		reason
	)
VALUES
	($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13) RETURNING id, created_at, updated_at, workspace_id, template_version_id, name, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason
`

type InsertWorkspaceBuildParams struct {
	ID                uuid.UUID           `db:"id" json:"id"`
	CreatedAt         time.Time           `db:"created_at" json:"created_at"`
	UpdatedAt         time.Time           `db:"updated_at" json:"updated_at"`
	WorkspaceID       uuid.UUID           `db:"workspace_id" json:"workspace_id"`
	TemplateVersionID uuid.UUID           `db:"template_version_id" json:"template_version_id"`
	BuildNumber       int32               `db:"build_number" json:"build_number"`
	Name              string              `db:"name" json:"name"`
	Transition        WorkspaceTransition `db:"transition" json:"transition"`
	InitiatorID       uuid.UUID           `db:"initiator_id" json:"initiator_id"`
	JobID             uuid.UUID           `db:"job_id" json:"job_id"`
	ProvisionerState  []byte              `db:"provisioner_state" json:"provisioner_state"`
	Deadline          time.Time           `db:"deadline" json:"deadline"`
	Reason            BuildReason         `db:"reason" json:"reason"`
}

func (q *sqlQuerier) InsertWorkspaceBuild(ctx context.Context, arg InsertWorkspaceBuildParams) (WorkspaceBuild, error) {
	row := q.db.QueryRowContext(ctx, insertWorkspaceBuild,
		arg.ID,
		arg.CreatedAt,
		arg.UpdatedAt,
		arg.WorkspaceID,
		arg.TemplateVersionID,
		arg.BuildNumber,
		arg.Name,
		arg.Transition,
		arg.InitiatorID,
		arg.JobID,
		arg.ProvisionerState,
		arg.Deadline,
		arg.Reason,
	)
	var i WorkspaceBuild
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.WorkspaceID,
		&i.TemplateVersionID,
		&i.Name,
		&i.BuildNumber,
		&i.Transition,
		&i.InitiatorID,
		&i.ProvisionerState,
		&i.JobID,
		&i.Deadline,
		&i.Reason,
	)
	return i, err
}

const updateWorkspaceBuildByID = `-- name: UpdateWorkspaceBuildByID :exec
UPDATE
	workspace_builds
SET
	updated_at = $2,
	provisioner_state = $3,
	deadline = $4
WHERE
	id = $1
`

type UpdateWorkspaceBuildByIDParams struct {
	ID               uuid.UUID `db:"id" json:"id"`
	UpdatedAt        time.Time `db:"updated_at" json:"updated_at"`
	ProvisionerState []byte    `db:"provisioner_state" json:"provisioner_state"`
	Deadline         time.Time `db:"deadline" json:"deadline"`
}

func (q *sqlQuerier) UpdateWorkspaceBuildByID(ctx context.Context, arg UpdateWorkspaceBuildByIDParams) error {
	_, err := q.db.ExecContext(ctx, updateWorkspaceBuildByID,
		arg.ID,
		arg.UpdatedAt,
		arg.ProvisionerState,
		arg.Deadline,
	)
	return err
}

const getWorkspaceResourceByID = `-- name: GetWorkspaceResourceByID :one
SELECT
	id, created_at, job_id, transition, type, name
FROM
	workspace_resources
WHERE
	id = $1
`

func (q *sqlQuerier) GetWorkspaceResourceByID(ctx context.Context, id uuid.UUID) (WorkspaceResource, error) {
	row := q.db.QueryRowContext(ctx, getWorkspaceResourceByID, id)
	var i WorkspaceResource
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.JobID,
		&i.Transition,
		&i.Type,
		&i.Name,
	)
	return i, err
}

const getWorkspaceResourceMetadataByResourceID = `-- name: GetWorkspaceResourceMetadataByResourceID :many
SELECT
	workspace_resource_id, key, value, sensitive
FROM
	workspace_resource_metadata
WHERE
	workspace_resource_id = $1
`

func (q *sqlQuerier) GetWorkspaceResourceMetadataByResourceID(ctx context.Context, workspaceResourceID uuid.UUID) ([]WorkspaceResourceMetadatum, error) {
	rows, err := q.db.QueryContext(ctx, getWorkspaceResourceMetadataByResourceID, workspaceResourceID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []WorkspaceResourceMetadatum
	for rows.Next() {
		var i WorkspaceResourceMetadatum
		if err := rows.Scan(
			&i.WorkspaceResourceID,
			&i.Key,
			&i.Value,
			&i.Sensitive,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getWorkspaceResourceMetadataByResourceIDs = `-- name: GetWorkspaceResourceMetadataByResourceIDs :many
SELECT
	workspace_resource_id, key, value, sensitive
FROM
	workspace_resource_metadata
WHERE
	workspace_resource_id = ANY($1 :: uuid [ ])
`

func (q *sqlQuerier) GetWorkspaceResourceMetadataByResourceIDs(ctx context.Context, ids []uuid.UUID) ([]WorkspaceResourceMetadatum, error) {
	rows, err := q.db.QueryContext(ctx, getWorkspaceResourceMetadataByResourceIDs, pq.Array(ids))
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []WorkspaceResourceMetadatum
	for rows.Next() {
		var i WorkspaceResourceMetadatum
		if err := rows.Scan(
			&i.WorkspaceResourceID,
			&i.Key,
			&i.Value,
			&i.Sensitive,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getWorkspaceResourceMetadataCreatedAfter = `-- name: GetWorkspaceResourceMetadataCreatedAfter :many
SELECT workspace_resource_id, key, value, sensitive FROM workspace_resource_metadata WHERE workspace_resource_id = ANY(
	SELECT id FROM workspace_resources WHERE created_at > $1
)
`

func (q *sqlQuerier) GetWorkspaceResourceMetadataCreatedAfter(ctx context.Context, createdAt time.Time) ([]WorkspaceResourceMetadatum, error) {
	rows, err := q.db.QueryContext(ctx, getWorkspaceResourceMetadataCreatedAfter, createdAt)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []WorkspaceResourceMetadatum
	for rows.Next() {
		var i WorkspaceResourceMetadatum
		if err := rows.Scan(
			&i.WorkspaceResourceID,
			&i.Key,
			&i.Value,
			&i.Sensitive,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getWorkspaceResourcesByJobID = `-- name: GetWorkspaceResourcesByJobID :many
SELECT
	id, created_at, job_id, transition, type, name
FROM
	workspace_resources
WHERE
	job_id = $1
`

func (q *sqlQuerier) GetWorkspaceResourcesByJobID(ctx context.Context, jobID uuid.UUID) ([]WorkspaceResource, error) {
	rows, err := q.db.QueryContext(ctx, getWorkspaceResourcesByJobID, jobID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []WorkspaceResource
	for rows.Next() {
		var i WorkspaceResource
		if err := rows.Scan(
			&i.ID,
			&i.CreatedAt,
			&i.JobID,
			&i.Transition,
			&i.Type,
			&i.Name,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getWorkspaceResourcesCreatedAfter = `-- name: GetWorkspaceResourcesCreatedAfter :many
SELECT id, created_at, job_id, transition, type, name FROM workspace_resources WHERE created_at > $1
`

func (q *sqlQuerier) GetWorkspaceResourcesCreatedAfter(ctx context.Context, createdAt time.Time) ([]WorkspaceResource, error) {
	rows, err := q.db.QueryContext(ctx, getWorkspaceResourcesCreatedAfter, createdAt)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []WorkspaceResource
	for rows.Next() {
		var i WorkspaceResource
		if err := rows.Scan(
			&i.ID,
			&i.CreatedAt,
			&i.JobID,
			&i.Transition,
			&i.Type,
			&i.Name,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const insertWorkspaceResource = `-- name: InsertWorkspaceResource :one
INSERT INTO
	workspace_resources (id, created_at, job_id, transition, type, name)
VALUES
	($1, $2, $3, $4, $5, $6) RETURNING id, created_at, job_id, transition, type, name
`

type InsertWorkspaceResourceParams struct {
	ID         uuid.UUID           `db:"id" json:"id"`
	CreatedAt  time.Time           `db:"created_at" json:"created_at"`
	JobID      uuid.UUID           `db:"job_id" json:"job_id"`
	Transition WorkspaceTransition `db:"transition" json:"transition"`
	Type       string              `db:"type" json:"type"`
	Name       string              `db:"name" json:"name"`
}

func (q *sqlQuerier) InsertWorkspaceResource(ctx context.Context, arg InsertWorkspaceResourceParams) (WorkspaceResource, error) {
	row := q.db.QueryRowContext(ctx, insertWorkspaceResource,
		arg.ID,
		arg.CreatedAt,
		arg.JobID,
		arg.Transition,
		arg.Type,
		arg.Name,
	)
	var i WorkspaceResource
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.JobID,
		&i.Transition,
		&i.Type,
		&i.Name,
	)
	return i, err
}

const insertWorkspaceResourceMetadata = `-- name: InsertWorkspaceResourceMetadata :one
INSERT INTO
	workspace_resource_metadata (workspace_resource_id, key, value, sensitive)
VALUES
	($1, $2, $3, $4) RETURNING workspace_resource_id, key, value, sensitive
`

type InsertWorkspaceResourceMetadataParams struct {
	WorkspaceResourceID uuid.UUID      `db:"workspace_resource_id" json:"workspace_resource_id"`
	Key                 string         `db:"key" json:"key"`
	Value               sql.NullString `db:"value" json:"value"`
	Sensitive           bool           `db:"sensitive" json:"sensitive"`
}

func (q *sqlQuerier) InsertWorkspaceResourceMetadata(ctx context.Context, arg InsertWorkspaceResourceMetadataParams) (WorkspaceResourceMetadatum, error) {
	row := q.db.QueryRowContext(ctx, insertWorkspaceResourceMetadata,
		arg.WorkspaceResourceID,
		arg.Key,
		arg.Value,
		arg.Sensitive,
	)
	var i WorkspaceResourceMetadatum
	err := row.Scan(
		&i.WorkspaceResourceID,
		&i.Key,
		&i.Value,
		&i.Sensitive,
	)
	return i, err
}

const getWorkspaceByID = `-- name: GetWorkspaceByID :one
SELECT
	id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl
FROM
	workspaces
WHERE
	id = $1
LIMIT
	1
`

func (q *sqlQuerier) GetWorkspaceByID(ctx context.Context, id uuid.UUID) (Workspace, error) {
	row := q.db.QueryRowContext(ctx, getWorkspaceByID, id)
	var i Workspace
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.OwnerID,
		&i.OrganizationID,
		&i.TemplateID,
		&i.Deleted,
		&i.Name,
		&i.AutostartSchedule,
		&i.Ttl,
	)
	return i, err
}

const getWorkspaceByOwnerIDAndName = `-- name: GetWorkspaceByOwnerIDAndName :one
SELECT
	id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl
FROM
	workspaces
WHERE
	owner_id = $1
	AND deleted = $2
	AND LOWER("name") = LOWER($3)
ORDER BY created_at DESC
`

type GetWorkspaceByOwnerIDAndNameParams struct {
	OwnerID uuid.UUID `db:"owner_id" json:"owner_id"`
	Deleted bool      `db:"deleted" json:"deleted"`
	Name    string    `db:"name" json:"name"`
}

func (q *sqlQuerier) GetWorkspaceByOwnerIDAndName(ctx context.Context, arg GetWorkspaceByOwnerIDAndNameParams) (Workspace, error) {
	row := q.db.QueryRowContext(ctx, getWorkspaceByOwnerIDAndName, arg.OwnerID, arg.Deleted, arg.Name)
	var i Workspace
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.OwnerID,
		&i.OrganizationID,
		&i.TemplateID,
		&i.Deleted,
		&i.Name,
		&i.AutostartSchedule,
		&i.Ttl,
	)
	return i, err
}

const getWorkspaceOwnerCountsByTemplateIDs = `-- name: GetWorkspaceOwnerCountsByTemplateIDs :many
SELECT
	template_id,
	COUNT(DISTINCT owner_id)
FROM
	workspaces
WHERE
	template_id = ANY($1 :: uuid [ ])
	-- Ignore deleted workspaces
	AND deleted != true
GROUP BY
	template_id
`

type GetWorkspaceOwnerCountsByTemplateIDsRow struct {
	TemplateID uuid.UUID `db:"template_id" json:"template_id"`
	Count      int64     `db:"count" json:"count"`
}

func (q *sqlQuerier) GetWorkspaceOwnerCountsByTemplateIDs(ctx context.Context, ids []uuid.UUID) ([]GetWorkspaceOwnerCountsByTemplateIDsRow, error) {
	rows, err := q.db.QueryContext(ctx, getWorkspaceOwnerCountsByTemplateIDs, pq.Array(ids))
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []GetWorkspaceOwnerCountsByTemplateIDsRow
	for rows.Next() {
		var i GetWorkspaceOwnerCountsByTemplateIDsRow
		if err := rows.Scan(&i.TemplateID, &i.Count); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getWorkspaces = `-- name: GetWorkspaces :many
SELECT
    id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl
FROM
    workspaces
WHERE
    -- Optionally include deleted workspaces
	workspaces.deleted = $1
	-- Filter by owner_id
	AND CASE
		WHEN $2 :: uuid != '00000000-00000000-00000000-00000000' THEN
			owner_id = $2
		ELSE true
	END
  	-- Filter by owner_name
	AND CASE
		WHEN $3 :: text != '' THEN
			owner_id = (SELECT id FROM users WHERE lower(username) = lower($3))
		ELSE true
	END
	-- Filter by template_name
	-- There can be more than 1 template with the same name across organizations.
  	-- Use the organization filter to restrict to 1 org if needed.
	AND CASE
		WHEN $4 :: text != '' THEN
			template_id = ANY(SELECT id FROM templates WHERE lower(name) = lower($4))
		ELSE true
	END
	-- Filter by template_ids
	AND CASE
		WHEN array_length($5 :: uuid[], 1) > 0 THEN
			template_id = ANY($5)
		ELSE true
	END
	-- Filter by name, matching on substring
	AND CASE
		WHEN $6 :: text != '' THEN
		    name ILIKE '%' || $6 || '%'
		ELSE true
	END
`

type GetWorkspacesParams struct {
	Deleted       bool        `db:"deleted" json:"deleted"`
	OwnerID       uuid.UUID   `db:"owner_id" json:"owner_id"`
	OwnerUsername string      `db:"owner_username" json:"owner_username"`
	TemplateName  string      `db:"template_name" json:"template_name"`
	TemplateIds   []uuid.UUID `db:"template_ids" json:"template_ids"`
	Name          string      `db:"name" json:"name"`
}

func (q *sqlQuerier) GetWorkspaces(ctx context.Context, arg GetWorkspacesParams) ([]Workspace, error) {
	rows, err := q.db.QueryContext(ctx, getWorkspaces,
		arg.Deleted,
		arg.OwnerID,
		arg.OwnerUsername,
		arg.TemplateName,
		pq.Array(arg.TemplateIds),
		arg.Name,
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []Workspace
	for rows.Next() {
		var i Workspace
		if err := rows.Scan(
			&i.ID,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.OwnerID,
			&i.OrganizationID,
			&i.TemplateID,
			&i.Deleted,
			&i.Name,
			&i.AutostartSchedule,
			&i.Ttl,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getWorkspacesAutostart = `-- name: GetWorkspacesAutostart :many
SELECT
	id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl
FROM
	workspaces
WHERE
	deleted = false
AND
(
	(autostart_schedule IS NOT NULL AND autostart_schedule <> '')
	OR
	(ttl IS NOT NULL AND ttl > 0)
)
`

func (q *sqlQuerier) GetWorkspacesAutostart(ctx context.Context) ([]Workspace, error) {
	rows, err := q.db.QueryContext(ctx, getWorkspacesAutostart)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []Workspace
	for rows.Next() {
		var i Workspace
		if err := rows.Scan(
			&i.ID,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.OwnerID,
			&i.OrganizationID,
			&i.TemplateID,
			&i.Deleted,
			&i.Name,
			&i.AutostartSchedule,
			&i.Ttl,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Close(); err != nil {
		return nil, err
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const insertWorkspace = `-- name: InsertWorkspace :one
INSERT INTO
	workspaces (
		id,
		created_at,
		updated_at,
		owner_id,
		organization_id,
		template_id,
		name,
		autostart_schedule,
		ttl
	)
VALUES
	($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl
`

type InsertWorkspaceParams struct {
	ID                uuid.UUID      `db:"id" json:"id"`
	CreatedAt         time.Time      `db:"created_at" json:"created_at"`
	UpdatedAt         time.Time      `db:"updated_at" json:"updated_at"`
	OwnerID           uuid.UUID      `db:"owner_id" json:"owner_id"`
	OrganizationID    uuid.UUID      `db:"organization_id" json:"organization_id"`
	TemplateID        uuid.UUID      `db:"template_id" json:"template_id"`
	Name              string         `db:"name" json:"name"`
	AutostartSchedule sql.NullString `db:"autostart_schedule" json:"autostart_schedule"`
	Ttl               sql.NullInt64  `db:"ttl" json:"ttl"`
}

func (q *sqlQuerier) InsertWorkspace(ctx context.Context, arg InsertWorkspaceParams) (Workspace, error) {
	row := q.db.QueryRowContext(ctx, insertWorkspace,
		arg.ID,
		arg.CreatedAt,
		arg.UpdatedAt,
		arg.OwnerID,
		arg.OrganizationID,
		arg.TemplateID,
		arg.Name,
		arg.AutostartSchedule,
		arg.Ttl,
	)
	var i Workspace
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.OwnerID,
		&i.OrganizationID,
		&i.TemplateID,
		&i.Deleted,
		&i.Name,
		&i.AutostartSchedule,
		&i.Ttl,
	)
	return i, err
}

const updateWorkspaceAutostart = `-- name: UpdateWorkspaceAutostart :exec
UPDATE
	workspaces
SET
	autostart_schedule = $2
WHERE
	id = $1
`

type UpdateWorkspaceAutostartParams struct {
	ID                uuid.UUID      `db:"id" json:"id"`
	AutostartSchedule sql.NullString `db:"autostart_schedule" json:"autostart_schedule"`
}

func (q *sqlQuerier) UpdateWorkspaceAutostart(ctx context.Context, arg UpdateWorkspaceAutostartParams) error {
	_, err := q.db.ExecContext(ctx, updateWorkspaceAutostart, arg.ID, arg.AutostartSchedule)
	return err
}

const updateWorkspaceDeletedByID = `-- name: UpdateWorkspaceDeletedByID :exec
UPDATE
	workspaces
SET
	deleted = $2
WHERE
	id = $1
`

type UpdateWorkspaceDeletedByIDParams struct {
	ID      uuid.UUID `db:"id" json:"id"`
	Deleted bool      `db:"deleted" json:"deleted"`
}

func (q *sqlQuerier) UpdateWorkspaceDeletedByID(ctx context.Context, arg UpdateWorkspaceDeletedByIDParams) error {
	_, err := q.db.ExecContext(ctx, updateWorkspaceDeletedByID, arg.ID, arg.Deleted)
	return err
}

const updateWorkspaceTTL = `-- name: UpdateWorkspaceTTL :exec
UPDATE
	workspaces
SET
	ttl = $2
WHERE
	id = $1
`

type UpdateWorkspaceTTLParams struct {
	ID  uuid.UUID     `db:"id" json:"id"`
	Ttl sql.NullInt64 `db:"ttl" json:"ttl"`
}

func (q *sqlQuerier) UpdateWorkspaceTTL(ctx context.Context, arg UpdateWorkspaceTTLParams) error {
	_, err := q.db.ExecContext(ctx, updateWorkspaceTTL, arg.ID, arg.Ttl)
	return err
}
