func (q *DBQuerier) InsertScreenshotBlocksBatch(batch genericBatch, screenshotID int, body string) {
	batch.Queue(insertScreenshotBlocksSQL, screenshotID, body)
}
InsertScreenshotBlocksBatch implements Querier.InsertScreenshotBlocksBatch.
package composite
import (
	"context"
	"fmt"
	"github.com/jackc/pgconn"
	"github.com/jackc/pgtype"
	"github.com/jackc/pgx/v4"
)
type Querier interface {
	SearchScreenshots(ctx context.Context, params SearchScreenshotsParams) ([]SearchScreenshotsRow, error)
	SearchScreenshotsBatch(batch genericBatch, params SearchScreenshotsParams)
	SearchScreenshotsScan(results pgx.BatchResults) ([]SearchScreenshotsRow, error)
	SearchScreenshotsOneCol(ctx context.Context, params SearchScreenshotsOneColParams) ([][]Blocks, error)
	SearchScreenshotsOneColBatch(batch genericBatch, params SearchScreenshotsOneColParams)
	SearchScreenshotsOneColScan(results pgx.BatchResults) ([][]Blocks, error)
	InsertScreenshotBlocks(ctx context.Context, screenshotID int, body string) (InsertScreenshotBlocksRow, error)
	InsertScreenshotBlocksBatch(batch genericBatch, screenshotID int, body string)
	InsertScreenshotBlocksScan(results pgx.BatchResults) (InsertScreenshotBlocksRow, error)
}
type DBQuerier struct {
	conn  genericConn    
	types *typeResolver  
}
var _ Querier = &DBQuerier{}
type genericConn interface {
	Query(ctx context.Context, sql string, args ...interface{}) (pgx.Rows, error)
	QueryRow(ctx context.Context, sql string, args ...interface{}) pgx.Row
	Exec(ctx context.Context, sql string, arguments ...interface{}) (pgconn.CommandTag, error)
}
type genericBatch interface {
	Queue(query string, arguments ...interface{})
}
func NewQuerier(conn genericConn) *DBQuerier {
	return NewQuerierConfig(conn, QuerierConfig{})
}
type QuerierConfig struct {
	DataTypes []pgtype.DataType
}
func NewQuerierConfig(conn genericConn, cfg QuerierConfig) *DBQuerier {
	return &DBQuerier{conn: conn, types: newTypeResolver(cfg.DataTypes)}
}
func (q *DBQuerier) WithTx(tx pgx.Tx) (*DBQuerier, error) {
	return &DBQuerier{conn: tx}, nil
}
type preparer interface {
	Prepare(ctx context.Context, name, sql string) (sd *pgconn.StatementDescription, err error)
}
func PrepareAllQueries(ctx context.Context, p preparer) error {
	if _, err := p.Prepare(ctx, searchScreenshotsSQL, searchScreenshotsSQL); err != nil {
		return fmt.Errorf("prepare query 'SearchScreenshots': %w", err)
	}
	if _, err := p.Prepare(ctx, searchScreenshotsOneColSQL, searchScreenshotsOneColSQL); err != nil {
		return fmt.Errorf("prepare query 'SearchScreenshotsOneCol': %w", err)
	}
	if _, err := p.Prepare(ctx, insertScreenshotBlocksSQL, insertScreenshotBlocksSQL); err != nil {
		return fmt.Errorf("prepare query 'InsertScreenshotBlocks': %w", err)
	}
	return nil
}
type Blocks struct {
	ID           int    `json:"id"`
	ScreenshotID int    `json:"screenshot_id"`
	Body         string `json:"body"`
}
type typeResolver struct {
	connInfo *pgtype.ConnInfo  
}
func newTypeResolver(types []pgtype.DataType) *typeResolver {
	ci := pgtype.NewConnInfo()
	for _, typ := range types {
		if txt, ok := typ.Value.(textPreferrer); ok && typ.OID != unknownOID {
			typ.Value = txt.ValueTranscoder
		}
		ci.RegisterDataType(typ)
	}
	return &typeResolver{connInfo: ci}
}
func (tr *typeResolver) findValue(name string) (uint32, pgtype.ValueTranscoder, bool) {
	typ, ok := tr.connInfo.DataTypeForName(name)
	if !ok {
		return 0, nil, false
	}
	v := pgtype.NewValue(typ.Value)
	return typ.OID, v.(pgtype.ValueTranscoder), true
}
func (tr *typeResolver) setValue(vt pgtype.ValueTranscoder, val interface{}) pgtype.ValueTranscoder {
	if err := vt.Set(val); err != nil {
		panic(fmt.Sprintf("set ValueTranscoder %T to %+v: %s", vt, val, err))
	}
	return vt
}
type compositeField struct {
	name       string                  
	typeName   string                  
	defaultVal pgtype.ValueTranscoder  
}
func (tr *typeResolver) newCompositeValue(name string, fields ...compositeField) pgtype.ValueTranscoder {
	if _, val, ok := tr.findValue(name); ok {
		return val
	}
	fs := make([]pgtype.CompositeTypeField, len(fields))
	vals := make([]pgtype.ValueTranscoder, len(fields))
	isBinaryOk := true
	for i, field := range fields {
		oid, val, ok := tr.findValue(field.typeName)
		if !ok {
			oid = unknownOID
			val = field.defaultVal
		}
		isBinaryOk = isBinaryOk && oid != unknownOID
		fs[i] = pgtype.CompositeTypeField{Name: field.name, OID: oid}
		vals[i] = val
	}
	typ, _ := pgtype.NewCompositeTypeValues(name, fs, vals)
	if !isBinaryOk {
		return textPreferrer{typ, name}
	}
	return typ
}
func (tr *typeResolver) newArrayValue(name, elemName string, defaultVal func() pgtype.ValueTranscoder) pgtype.ValueTranscoder {
	if _, val, ok := tr.findValue(name); ok {
		return val
	}
	elemOID, elemVal, ok := tr.findValue(elemName)
	elemValFunc := func() pgtype.ValueTranscoder {
		return pgtype.NewValue(elemVal).(pgtype.ValueTranscoder)
	}
	if !ok {
		elemOID = unknownOID
		elemValFunc = defaultVal
	}
	typ := pgtype.NewArrayType(name, elemOID, elemValFunc)
	if elemOID == unknownOID {
		return textPreferrer{typ, name}
	}
	return typ
}
func (tr *typeResolver) newBlocks() pgtype.ValueTranscoder {
	return tr.newCompositeValue(
		"blocks",
		compositeField{"id", "int4", &pgtype.Int4{}},
		compositeField{"screenshot_id", "int8", &pgtype.Int8{}},
		compositeField{"body", "text", &pgtype.Text{}},
	)
}
func (tr *typeResolver) newBlocksArray() pgtype.ValueTranscoder {
	return tr.newArrayValue("_blocks", "blocks", tr.newBlocks)
}
const searchScreenshotsSQL = `SELECT
  ss.id,
  array_agg(bl) AS blocks
FROM screenshots ss
  JOIN blocks bl ON bl.screenshot_id = ss.id
WHERE bl.body LIKE $1 || '%'
GROUP BY ss.id
ORDER BY ss.id
LIMIT $2 OFFSET $3;`
type SearchScreenshotsParams struct {
	Body   string
	Limit  int
	Offset int
}
type SearchScreenshotsRow struct {
	ID     int      `json:"id"`
	Blocks []Blocks `json:"blocks"`
}
func (q *DBQuerier) SearchScreenshots(ctx context.Context, params SearchScreenshotsParams) ([]SearchScreenshotsRow, error) {
	ctx = context.WithValue(ctx, "pggen_query_name", "SearchScreenshots")
	rows, err := q.conn.Query(ctx, searchScreenshotsSQL, params.Body, params.Limit, params.Offset)
	if err != nil {
		return nil, fmt.Errorf("query SearchScreenshots: %w", err)
	}
	defer rows.Close()
	items := []SearchScreenshotsRow{}
	blocksArray := q.types.newBlocksArray()
	for rows.Next() {
		var item SearchScreenshotsRow
		if err := rows.Scan(&item.ID, blocksArray); err != nil {
			return nil, fmt.Errorf("scan SearchScreenshots row: %w", err)
		}
		if err := blocksArray.AssignTo(&item.Blocks); err != nil {
			return nil, fmt.Errorf("assign SearchScreenshots row: %w", err)
		}
		items = append(items, item)
	}
	if err := rows.Err(); err != nil {
		return nil, fmt.Errorf("close SearchScreenshots rows: %w", err)
	}
	return items, err
}
func (q *DBQuerier) SearchScreenshotsBatch(batch genericBatch, params SearchScreenshotsParams) {
	batch.Queue(searchScreenshotsSQL, params.Body, params.Limit, params.Offset)
}
func (q *DBQuerier) SearchScreenshotsScan(results pgx.BatchResults) ([]SearchScreenshotsRow, error) {
	rows, err := results.Query()
	if err != nil {
		return nil, fmt.Errorf("query SearchScreenshotsBatch: %w", err)
	}
	defer rows.Close()
	items := []SearchScreenshotsRow{}
	blocksArray := q.types.newBlocksArray()
	for rows.Next() {
		var item SearchScreenshotsRow
		if err := rows.Scan(&item.ID, blocksArray); err != nil {
			return nil, fmt.Errorf("scan SearchScreenshotsBatch row: %w", err)
		}
		if err := blocksArray.AssignTo(&item.Blocks); err != nil {
			return nil, fmt.Errorf("assign SearchScreenshots row: %w", err)
		}
		items = append(items, item)
	}
	if err := rows.Err(); err != nil {
		return nil, fmt.Errorf("close SearchScreenshotsBatch rows: %w", err)
	}
	return items, err
}
const searchScreenshotsOneColSQL = `SELECT
  array_agg(bl) AS blocks
FROM screenshots ss
  JOIN blocks bl ON bl.screenshot_id = ss.id
WHERE bl.body LIKE $1 || '%'
GROUP BY ss.id
ORDER BY ss.id
LIMIT $2 OFFSET $3;`
type SearchScreenshotsOneColParams struct {
	Body   string
	Limit  int
	Offset int
}
func (q *DBQuerier) SearchScreenshotsOneCol(ctx context.Context, params SearchScreenshotsOneColParams) ([][]Blocks, error) {
	ctx = context.WithValue(ctx, "pggen_query_name", "SearchScreenshotsOneCol")
	rows, err := q.conn.Query(ctx, searchScreenshotsOneColSQL, params.Body, params.Limit, params.Offset)
	if err != nil {
		return nil, fmt.Errorf("query SearchScreenshotsOneCol: %w", err)
	}
	defer rows.Close()
	items := [][]Blocks{}
	blocksArray := q.types.newBlocksArray()
	for rows.Next() {
		var item []Blocks
		if err := rows.Scan(blocksArray); err != nil {
			return nil, fmt.Errorf("scan SearchScreenshotsOneCol row: %w", err)
		}
		if err := blocksArray.AssignTo(&item); err != nil {
			return nil, fmt.Errorf("assign SearchScreenshotsOneCol row: %w", err)
		}
		items = append(items, item)
	}
	if err := rows.Err(); err != nil {
		return nil, fmt.Errorf("close SearchScreenshotsOneCol rows: %w", err)
	}
	return items, err
}
func (q *DBQuerier) SearchScreenshotsOneColBatch(batch genericBatch, params SearchScreenshotsOneColParams) {
	batch.Queue(searchScreenshotsOneColSQL, params.Body, params.Limit, params.Offset)
}
func (q *DBQuerier) SearchScreenshotsOneColScan(results pgx.BatchResults) ([][]Blocks, error) {
	rows, err := results.Query()
	if err != nil {
		return nil, fmt.Errorf("query SearchScreenshotsOneColBatch: %w", err)
	}
	defer rows.Close()
	items := [][]Blocks{}
	blocksArray := q.types.newBlocksArray()
	for rows.Next() {
		var item []Blocks
		if err := rows.Scan(blocksArray); err != nil {
			return nil, fmt.Errorf("scan SearchScreenshotsOneColBatch row: %w", err)
		}
		if err := blocksArray.AssignTo(&item); err != nil {
			return nil, fmt.Errorf("assign SearchScreenshotsOneCol row: %w", err)
		}
		items = append(items, item)
	}
	if err := rows.Err(); err != nil {
		return nil, fmt.Errorf("close SearchScreenshotsOneColBatch rows: %w", err)
	}
	return items, err
}
const insertScreenshotBlocksSQL = `WITH screens AS (
  INSERT INTO screenshots (id) VALUES ($1)
    ON CONFLICT DO NOTHING
)
INSERT
INTO blocks (screenshot_id, body)
VALUES ($1, $2)
RETURNING id, screenshot_id, body;`
type InsertScreenshotBlocksRow struct {
	ID           int    `json:"id"`
	ScreenshotID int    `json:"screenshot_id"`
	Body         string `json:"body"`
}
func (q *DBQuerier) InsertScreenshotBlocks(ctx context.Context, screenshotID int, body string) (InsertScreenshotBlocksRow, error) {
	ctx = context.WithValue(ctx, "pggen_query_name", "InsertScreenshotBlocks")
	row := q.conn.QueryRow(ctx, insertScreenshotBlocksSQL, screenshotID, body)
	var item InsertScreenshotBlocksRow
	if err := row.Scan(&item.ID, &item.ScreenshotID, &item.Body); err != nil {
		return item, fmt.Errorf("query InsertScreenshotBlocks: %w", err)
	}
	return item, nil
}