// Code generated by sqlc. DO NOT EDIT.
// versions:
//   sqlc v1.29.0
// source: payload-store.sql

package sqlcv1

import (
	"context"

	"github.com/google/uuid"
	"github.com/jackc/pgx/v5/pgtype"
)

const acquireOrExtendCutoverJobLease = `-- name: AcquireOrExtendCutoverJobLease :one
WITH inputs AS (
    SELECT
        $2::DATE AS key,
        $1::UUID AS lease_process_id,
        $3::TIMESTAMPTZ AS lease_expires_at,
        $4::UUID AS last_external_id
), any_lease_held_by_other_process AS (
    -- need coalesce here in case there are no rows that don't belong to this process
    SELECT COALESCE(BOOL_OR(lease_expires_at > NOW()), FALSE) AS lease_exists
    FROM v1_payload_cutover_job_offset
    WHERE lease_process_id != $1::UUID
), to_insert AS (
    SELECT key, lease_process_id, lease_expires_at, last_external_id
    FROM inputs
    -- if a lease is held by another process, we shouldn't try to insert a new row regardless
    -- of which key we're trying to acquire a lease on
    WHERE NOT (SELECT lease_exists FROM any_lease_held_by_other_process)
)

INSERT INTO v1_payload_cutover_job_offset (key, lease_process_id, lease_expires_at, last_external_id)
SELECT ti.key, ti.lease_process_id, ti.lease_expires_at, ti.last_external_id
FROM to_insert ti
ON CONFLICT (key)
DO UPDATE SET
    -- if the lease is held by this process, then we extend the offset to the new tuple of (last_tenant_id, last_inserted_at, last_id, last_type)
    -- otherwise it's a new process acquiring the lease, so we should keep the offset where it was before
    last_external_id = CASE
        WHEN EXCLUDED.lease_process_id = v1_payload_cutover_job_offset.lease_process_id THEN EXCLUDED.last_external_id
        ELSE v1_payload_cutover_job_offset.last_external_id
    END,

    lease_process_id = EXCLUDED.lease_process_id,
    lease_expires_at = EXCLUDED.lease_expires_at
WHERE v1_payload_cutover_job_offset.lease_expires_at < NOW() OR v1_payload_cutover_job_offset.lease_process_id = $1::UUID
RETURNING key, is_completed, lease_process_id, lease_expires_at, last_external_id
`

type AcquireOrExtendCutoverJobLeaseParams struct {
	Leaseprocessid uuid.UUID          `json:"leaseprocessid"`
	Key            pgtype.Date        `json:"key"`
	Leaseexpiresat pgtype.Timestamptz `json:"leaseexpiresat"`
	Lastexternalid uuid.UUID          `json:"lastexternalid"`
}

func (q *Queries) AcquireOrExtendCutoverJobLease(ctx context.Context, db DBTX, arg AcquireOrExtendCutoverJobLeaseParams) (*V1PayloadCutoverJobOffset, error) {
	row := db.QueryRow(ctx, acquireOrExtendCutoverJobLease,
		arg.Leaseprocessid,
		arg.Key,
		arg.Leaseexpiresat,
		arg.Lastexternalid,
	)
	var i V1PayloadCutoverJobOffset
	err := row.Scan(
		&i.Key,
		&i.IsCompleted,
		&i.LeaseProcessID,
		&i.LeaseExpiresAt,
		&i.LastExternalID,
	)
	return &i, err
}

const analyzeV1Payload = `-- name: AnalyzeV1Payload :exec
ANALYZE v1_payload
`

func (q *Queries) AnalyzeV1Payload(ctx context.Context, db DBTX) error {
	_, err := db.Exec(ctx, analyzeV1Payload)
	return err
}

const cleanUpCutoverJobOffsets = `-- name: CleanUpCutoverJobOffsets :exec
DELETE FROM v1_payload_cutover_job_offset
WHERE NOT key = ANY($1::DATE[])
`

func (q *Queries) CleanUpCutoverJobOffsets(ctx context.Context, db DBTX, keystokeep []pgtype.Date) error {
	_, err := db.Exec(ctx, cleanUpCutoverJobOffsets, keystokeep)
	return err
}

const computePayloadBatchSize = `-- name: ComputePayloadBatchSize :one
SELECT compute_payload_batch_size(
    $1::DATE,
    $2::UUID,
    $3::INTEGER
) AS total_size_bytes
`

type ComputePayloadBatchSizeParams struct {
	Partitiondate  pgtype.Date `json:"partitiondate"`
	Lastexternalid uuid.UUID   `json:"lastexternalid"`
	Batchsize      int32       `json:"batchsize"`
}

func (q *Queries) ComputePayloadBatchSize(ctx context.Context, db DBTX, arg ComputePayloadBatchSizeParams) (int64, error) {
	row := db.QueryRow(ctx, computePayloadBatchSize, arg.Partitiondate, arg.Lastexternalid, arg.Batchsize)
	var total_size_bytes int64
	err := row.Scan(&total_size_bytes)
	return total_size_bytes, err
}

const createOffloadedPayloadIndexBlock = `-- name: CreateOffloadedPayloadIndexBlock :exec
INSERT INTO v1_payload_offloaded_block_index (
    payload_inserted_at_date,
    block_external_id_range,
    index_file_key
)
VALUES (
    $1::DATE,
    uuidrange($2::UUID, $3::UUID, '(]'),
    $4::TEXT
)
ON CONFLICT ON CONSTRAINT v1_payload_offloaded_block_index_date_range_excl DO NOTHING
`

type CreateOffloadedPayloadIndexBlockParams struct {
	Payloadinsertedatdate     pgtype.Date `json:"payloadinsertedatdate"`
	Blocklowerexternalidbound uuid.UUID   `json:"blocklowerexternalidbound"`
	Blockupperexternalidbound uuid.UUID   `json:"blockupperexternalidbound"`
	Indexfilekey              string      `json:"indexfilekey"`
}

func (q *Queries) CreateOffloadedPayloadIndexBlock(ctx context.Context, db DBTX, arg CreateOffloadedPayloadIndexBlockParams) error {
	_, err := db.Exec(ctx, createOffloadedPayloadIndexBlock,
		arg.Payloadinsertedatdate,
		arg.Blocklowerexternalidbound,
		arg.Blockupperexternalidbound,
		arg.Indexfilekey,
	)
	return err
}

const createPayloadRangeChunks = `-- name: CreatePayloadRangeChunks :many
WITH chunks AS (
    SELECT
        (p).*
    FROM create_payload_offload_range_chunks(
        $1::DATE,
        $2::INTEGER,
        $3::INTEGER,
        $4::UUID
    ) p
)

SELECT
    lower_external_id::UUID,
    upper_external_id::UUID
FROM chunks
`

type CreatePayloadRangeChunksParams struct {
	Partitiondate  pgtype.Date `json:"partitiondate"`
	Windowsize     int32       `json:"windowsize"`
	Chunksize      int32       `json:"chunksize"`
	Lastexternalid uuid.UUID   `json:"lastexternalid"`
}

type CreatePayloadRangeChunksRow struct {
	LowerExternalID uuid.UUID `json:"lower_external_id"`
	UpperExternalID uuid.UUID `json:"upper_external_id"`
}

func (q *Queries) CreatePayloadRangeChunks(ctx context.Context, db DBTX, arg CreatePayloadRangeChunksParams) ([]*CreatePayloadRangeChunksRow, error) {
	rows, err := db.Query(ctx, createPayloadRangeChunks,
		arg.Partitiondate,
		arg.Windowsize,
		arg.Chunksize,
		arg.Lastexternalid,
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*CreatePayloadRangeChunksRow
	for rows.Next() {
		var i CreatePayloadRangeChunksRow
		if err := rows.Scan(&i.LowerExternalID, &i.UpperExternalID); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const createV1PayloadCutoverTemporaryTable = `-- name: CreateV1PayloadCutoverTemporaryTable :exec
SELECT copy_v1_payload_partition_structure($1::DATE)
`

func (q *Queries) CreateV1PayloadCutoverTemporaryTable(ctx context.Context, db DBTX, date pgtype.Date) error {
	_, err := db.Exec(ctx, createV1PayloadCutoverTemporaryTable, date)
	return err
}

const deleteOldPayloadOffloadedBlockIndexRows = `-- name: DeleteOldPayloadOffloadedBlockIndexRows :exec
DELETE FROM v1_payload_offloaded_block_index
WHERE payload_inserted_at_date < $1::DATE
`

func (q *Queries) DeleteOldPayloadOffloadedBlockIndexRows(ctx context.Context, db DBTX, before pgtype.Date) error {
	_, err := db.Exec(ctx, deleteOldPayloadOffloadedBlockIndexRows, before)
	return err
}

const getOffloadedPayloadIndexBlocks = `-- name: GetOffloadedPayloadIndexBlocks :many
WITH inputs AS (
    SELECT
        UNNEST($1::DATE[]) AS inserted_at_date,
        UNNEST($2::UUID[]) AS external_id
)

SELECT i.external_id::UUID AS external_id, index_file_key
FROM v1_payload_offloaded_block_index p
JOIN inputs i ON
    p.payload_inserted_at_date = i.inserted_at_date
    AND p.block_external_id_range @> i.external_id
`

type GetOffloadedPayloadIndexBlocksParams struct {
	Insertedats []pgtype.Date `json:"insertedats"`
	Externalids []uuid.UUID   `json:"externalids"`
}

type GetOffloadedPayloadIndexBlocksRow struct {
	ExternalID   uuid.UUID `json:"external_id"`
	IndexFileKey string    `json:"index_file_key"`
}

func (q *Queries) GetOffloadedPayloadIndexBlocks(ctx context.Context, db DBTX, arg GetOffloadedPayloadIndexBlocksParams) ([]*GetOffloadedPayloadIndexBlocksRow, error) {
	rows, err := db.Query(ctx, getOffloadedPayloadIndexBlocks, arg.Insertedats, arg.Externalids)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*GetOffloadedPayloadIndexBlocksRow
	for rows.Next() {
		var i GetOffloadedPayloadIndexBlocksRow
		if err := rows.Scan(&i.ExternalID, &i.IndexFileKey); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listPaginatedPayloadsForOffload = `-- name: ListPaginatedPayloadsForOffload :many
WITH payloads AS (
    SELECT
        (p).*
    FROM list_paginated_payloads_for_offload(
        $1::DATE,
        $2::UUID,
        $3::UUID,
        $4::INTEGER
    ) p
)
SELECT
    tenant_id::UUID,
    id::BIGINT,
    inserted_at::TIMESTAMPTZ,
    external_id::UUID,
    type::v1_payload_type,
    location::v1_payload_location,
    COALESCE(external_location_key, '')::TEXT AS external_location_key,
    inline_content::JSONB AS inline_content,
    updated_at::TIMESTAMPTZ
FROM payloads
`

type ListPaginatedPayloadsForOffloadParams struct {
	Partitiondate  pgtype.Date `json:"partitiondate"`
	Lastexternalid uuid.UUID   `json:"lastexternalid"`
	Nextexternalid uuid.UUID   `json:"nextexternalid"`
	Batchsize      int32       `json:"batchsize"`
}

type ListPaginatedPayloadsForOffloadRow struct {
	TenantID            uuid.UUID          `json:"tenant_id"`
	ID                  int64              `json:"id"`
	InsertedAt          pgtype.Timestamptz `json:"inserted_at"`
	ExternalID          uuid.UUID          `json:"external_id"`
	Type                V1PayloadType      `json:"type"`
	Location            V1PayloadLocation  `json:"location"`
	ExternalLocationKey string             `json:"external_location_key"`
	InlineContent       []byte             `json:"inline_content"`
	UpdatedAt           pgtype.Timestamptz `json:"updated_at"`
}

func (q *Queries) ListPaginatedPayloadsForOffload(ctx context.Context, db DBTX, arg ListPaginatedPayloadsForOffloadParams) ([]*ListPaginatedPayloadsForOffloadRow, error) {
	rows, err := db.Query(ctx, listPaginatedPayloadsForOffload,
		arg.Partitiondate,
		arg.Lastexternalid,
		arg.Nextexternalid,
		arg.Batchsize,
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*ListPaginatedPayloadsForOffloadRow
	for rows.Next() {
		var i ListPaginatedPayloadsForOffloadRow
		if err := rows.Scan(
			&i.TenantID,
			&i.ID,
			&i.InsertedAt,
			&i.ExternalID,
			&i.Type,
			&i.Location,
			&i.ExternalLocationKey,
			&i.InlineContent,
			&i.UpdatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const markCutoverJobAsCompleted = `-- name: MarkCutoverJobAsCompleted :exec
UPDATE v1_payload_cutover_job_offset
SET is_completed = TRUE
WHERE key = $1::DATE
`

func (q *Queries) MarkCutoverJobAsCompleted(ctx context.Context, db DBTX, key pgtype.Date) error {
	_, err := db.Exec(ctx, markCutoverJobAsCompleted, key)
	return err
}

const readPayloads = `-- name: ReadPayloads :many
WITH inputs AS (
    SELECT
        UNNEST($1::BIGINT[]) AS id,
        UNNEST($2::TIMESTAMPTZ[]) AS inserted_at,
        UNNEST($3::UUID[]) AS tenant_id,
        UNNEST(CAST($4::TEXT[] AS v1_payload_type[])) AS type
)

SELECT tenant_id, id, inserted_at, external_id, type, location, external_location_key, inline_content, updated_at
FROM v1_payload
WHERE (tenant_id, id, inserted_at, type) IN (
        SELECT tenant_id, id, inserted_at, type
        FROM inputs
    )
`

type ReadPayloadsParams struct {
	Ids         []int64              `json:"ids"`
	Insertedats []pgtype.Timestamptz `json:"insertedats"`
	Tenantids   []uuid.UUID          `json:"tenantids"`
	Types       []string             `json:"types"`
}

func (q *Queries) ReadPayloads(ctx context.Context, db DBTX, arg ReadPayloadsParams) ([]*V1Payload, error) {
	rows, err := db.Query(ctx, readPayloads,
		arg.Ids,
		arg.Insertedats,
		arg.Tenantids,
		arg.Types,
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*V1Payload
	for rows.Next() {
		var i V1Payload
		if err := rows.Scan(
			&i.TenantID,
			&i.ID,
			&i.InsertedAt,
			&i.ExternalID,
			&i.Type,
			&i.Location,
			&i.ExternalLocationKey,
			&i.InlineContent,
			&i.UpdatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const swapV1PayloadPartitionWithTemp = `-- name: SwapV1PayloadPartitionWithTemp :exec
SELECT swap_v1_payload_partition_with_temp($1::DATE)
`

func (q *Queries) SwapV1PayloadPartitionWithTemp(ctx context.Context, db DBTX, date pgtype.Date) error {
	_, err := db.Exec(ctx, swapV1PayloadPartitionWithTemp, date)
	return err
}

const writePayloads = `-- name: WritePayloads :exec
WITH inputs AS (
    SELECT DISTINCT
        UNNEST($1::BIGINT[]) AS id,
        UNNEST($2::TIMESTAMPTZ[]) AS inserted_at,
        UNNEST($3::UUID[]) AS external_id,
        UNNEST(CAST($4::TEXT[] AS v1_payload_type[])) AS type,
        UNNEST(CAST($5::TEXT[] AS v1_payload_location[])) AS location,
        UNNEST($6::TEXT[]) AS external_location_key,
        UNNEST($7::JSONB[]) AS inline_content,
        UNNEST($8::UUID[]) AS tenant_id
)

INSERT INTO v1_payload (
    tenant_id,
    id,
    inserted_at,
    external_id,
    type,
    location,
    external_location_key,
    inline_content
)
SELECT
    i.tenant_id,
    i.id,
    i.inserted_at,
    i.external_id,
    i.type,
    i.location,
    CASE WHEN i.external_location_key = '' OR i.location != 'EXTERNAL' THEN NULL ELSE i.external_location_key END,
    i.inline_content
FROM
    inputs i
ORDER BY i.tenant_id, i.inserted_at, i.id, i.type
ON CONFLICT (tenant_id, id, inserted_at, type)
DO UPDATE SET
    location = EXCLUDED.location,
    external_location_key = CASE WHEN EXCLUDED.external_location_key = '' OR EXCLUDED.location != 'EXTERNAL' THEN NULL ELSE EXCLUDED.external_location_key END,
    inline_content = EXCLUDED.inline_content,
    updated_at = NOW()
`

type WritePayloadsParams struct {
	Ids                  []int64              `json:"ids"`
	Insertedats          []pgtype.Timestamptz `json:"insertedats"`
	Externalids          []uuid.UUID          `json:"externalids"`
	Types                []string             `json:"types"`
	Locations            []string             `json:"locations"`
	Externallocationkeys []string             `json:"externallocationkeys"`
	Inlinecontents       [][]byte             `json:"inlinecontents"`
	Tenantids            []uuid.UUID          `json:"tenantids"`
}

func (q *Queries) WritePayloads(ctx context.Context, db DBTX, arg WritePayloadsParams) error {
	_, err := db.Exec(ctx, writePayloads,
		arg.Ids,
		arg.Insertedats,
		arg.Externalids,
		arg.Types,
		arg.Locations,
		arg.Externallocationkeys,
		arg.Inlinecontents,
		arg.Tenantids,
	)
	return err
}
