// Code generated by sqlc. DO NOT EDIT. // versions: // sqlc v1.31.1 // source: sam.sql package dbgen import ( "context" "time" "github.com/jackc/pgx/v5/pgtype" ) const getSamOpportunity = `-- name: GetSamOpportunity :one SELECT notice_id, title, solicitation_number, department, full_parent_path, sub_agency, naics_code, psc_code, set_aside_code, set_aside, notice_type, base_type, posted_date, response_deadline, active, pop_city, pop_state, pop_zip, ui_link, description_url, resource_links, poc, raw, source, synced_at FROM sam_opportunities WHERE notice_id = $1 ` func (q *Queries) GetSamOpportunity(ctx context.Context, noticeID string) (SamOpportunity, error) { row := q.db.QueryRow(ctx, getSamOpportunity, noticeID) var i SamOpportunity err := row.Scan( &i.NoticeID, &i.Title, &i.SolicitationNumber, &i.Department, &i.FullParentPath, &i.SubAgency, &i.NaicsCode, &i.PscCode, &i.SetAsideCode, &i.SetAside, &i.NoticeType, &i.BaseType, &i.PostedDate, &i.ResponseDeadline, &i.Active, &i.PopCity, &i.PopState, &i.PopZip, &i.UiLink, &i.DescriptionUrl, &i.ResourceLinks, &i.Poc, &i.Raw, &i.Source, &i.SyncedAt, ) return i, err } const listSamOpportunities = `-- name: ListSamOpportunities :many SELECT notice_id, title, solicitation_number, department, full_parent_path, sub_agency, naics_code, psc_code, set_aside_code, set_aside, notice_type, base_type, posted_date, response_deadline, active, pop_city, pop_state, pop_zip, ui_link, description_url, resource_links, poc, raw, source, synced_at FROM sam_opportunities WHERE ($1::text[] IS NULL OR naics_code = ANY($1::text[])) AND ($2::text[] IS NULL OR upper(set_aside_code) = ANY($2::text[])) AND ($3::text[] IS NULL OR upper(pop_state) = ANY($3::text[])) AND ($4::text[] IS NULL OR upper(department) = ANY($4::text[])) AND ($5::text[] IS NULL OR upper(sub_agency) = ANY($5::text[])) AND ($6::text IS NULL OR position(lower($6::text) in lower(title)) > 0) AND (NOT $7::boolean OR active = true) ORDER BY (response_deadline IS NULL OR response_deadline < now()), response_deadline ASC, posted_date DESC NULLS LAST, notice_id LIMIT $8::int ` type ListSamOpportunitiesParams struct { Naics []string `json:"naics"` SetAsides []string `json:"set_asides"` States []string `json:"states"` Departments []string `json:"departments"` SubAgencies []string `json:"sub_agencies"` Q *string `json:"q"` ActiveOnly bool `json:"active_only"` Lim int32 `json:"lim"` } // All filters are optional (NULL array / NULL scalar = "no filter"). active_only defaults true at the // handler. Soonest-closing first, then most-recently-posted. // Text equality filters are case-insensitive (upper() both sides; the service upper-cases the params) // so casing drift from SAM's path text can't silently zero out results [review COR-3]. The title search // is a literal substring (position()), NOT a LIKE pattern, so q's %/_/\ are matched literally and a // trailing backslash can't 500 the request [review COR-1]. Past-deadline / null-deadline notices sort // to the bottom so the feed leads with what's still open [review COR-2]. func (q *Queries) ListSamOpportunities(ctx context.Context, arg ListSamOpportunitiesParams) ([]SamOpportunity, error) { rows, err := q.db.Query(ctx, listSamOpportunities, arg.Naics, arg.SetAsides, arg.States, arg.Departments, arg.SubAgencies, arg.Q, arg.ActiveOnly, arg.Lim, ) if err != nil { return nil, err } defer rows.Close() items := []SamOpportunity{} for rows.Next() { var i SamOpportunity if err := rows.Scan( &i.NoticeID, &i.Title, &i.SolicitationNumber, &i.Department, &i.FullParentPath, &i.SubAgency, &i.NaicsCode, &i.PscCode, &i.SetAsideCode, &i.SetAside, &i.NoticeType, &i.BaseType, &i.PostedDate, &i.ResponseDeadline, &i.Active, &i.PopCity, &i.PopState, &i.PopZip, &i.UiLink, &i.DescriptionUrl, &i.ResourceLinks, &i.Poc, &i.Raw, &i.Source, &i.SyncedAt, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const samSyncMeta = `-- name: SamSyncMeta :one SELECT COUNT(*)::bigint AS total, MAX(synced_at) AS last_synced FROM sam_opportunities ` type SamSyncMetaRow struct { Total int64 `json:"total"` LastSynced interface{} `json:"last_synced"` } func (q *Queries) SamSyncMeta(ctx context.Context) (SamSyncMetaRow, error) { row := q.db.QueryRow(ctx, samSyncMeta) var i SamSyncMetaRow err := row.Scan(&i.Total, &i.LastSynced) return i, err } const upsertSamOpportunity = `-- name: UpsertSamOpportunity :exec INSERT INTO sam_opportunities ( notice_id, title, solicitation_number, department, full_parent_path, sub_agency, naics_code, psc_code, set_aside_code, set_aside, notice_type, base_type, posted_date, response_deadline, active, pop_city, pop_state, pop_zip, ui_link, description_url, resource_links, poc, raw, source, synced_at ) VALUES ( $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, now() ) ON CONFLICT (notice_id) DO UPDATE SET title = EXCLUDED.title, solicitation_number = EXCLUDED.solicitation_number, department = EXCLUDED.department, full_parent_path = EXCLUDED.full_parent_path, sub_agency = EXCLUDED.sub_agency, naics_code = EXCLUDED.naics_code, psc_code = EXCLUDED.psc_code, set_aside_code = EXCLUDED.set_aside_code, set_aside = EXCLUDED.set_aside, notice_type = EXCLUDED.notice_type, base_type = EXCLUDED.base_type, posted_date = EXCLUDED.posted_date, response_deadline = EXCLUDED.response_deadline, active = EXCLUDED.active, pop_city = EXCLUDED.pop_city, pop_state = EXCLUDED.pop_state, pop_zip = EXCLUDED.pop_zip, ui_link = EXCLUDED.ui_link, description_url = EXCLUDED.description_url, resource_links = EXCLUDED.resource_links, poc = EXCLUDED.poc, raw = EXCLUDED.raw, source = EXCLUDED.source, synced_at = now() ` type UpsertSamOpportunityParams struct { NoticeID string `json:"notice_id"` Title string `json:"title"` SolicitationNumber string `json:"solicitation_number"` Department string `json:"department"` FullParentPath string `json:"full_parent_path"` SubAgency string `json:"sub_agency"` NaicsCode string `json:"naics_code"` PscCode string `json:"psc_code"` SetAsideCode string `json:"set_aside_code"` SetAside string `json:"set_aside"` NoticeType string `json:"notice_type"` BaseType string `json:"base_type"` PostedDate pgtype.Date `json:"posted_date"` ResponseDeadline *time.Time `json:"response_deadline"` Active bool `json:"active"` PopCity string `json:"pop_city"` PopState string `json:"pop_state"` PopZip string `json:"pop_zip"` UiLink string `json:"ui_link"` DescriptionUrl string `json:"description_url"` ResourceLinks []byte `json:"resource_links"` Poc []byte `json:"poc"` Raw []byte `json:"raw"` Source string `json:"source"` } // SAM.gov opportunities cache. Global public catalog (no organization_id, outside RLS): reads run // straight off the pool, writes come from the daily sync (cmd/sam-sync) as the migrator role. func (q *Queries) UpsertSamOpportunity(ctx context.Context, arg UpsertSamOpportunityParams) error { _, err := q.db.Exec(ctx, upsertSamOpportunity, arg.NoticeID, arg.Title, arg.SolicitationNumber, arg.Department, arg.FullParentPath, arg.SubAgency, arg.NaicsCode, arg.PscCode, arg.SetAsideCode, arg.SetAside, arg.NoticeType, arg.BaseType, arg.PostedDate, arg.ResponseDeadline, arg.Active, arg.PopCity, arg.PopState, arg.PopZip, arg.UiLink, arg.DescriptionUrl, arg.ResourceLinks, arg.Poc, arg.Raw, arg.Source, ) return err }