dataflow/database/queries/records.sql
Paul Trowbridge 291c665ed1 Consolidate all SQL into database/queries/, switch to literal SQL in routes
- Add database/queries/{sources,rules,mappings,records}.sql — one file per
  route, all business logic in PostgreSQL functions
- Replace parameterized queries in all four route files with lit()/jsonLit()
  literal interpolation for debuggability
- Add api/lib/sql.js with lit(), jsonLit(), arr() helpers
- Fix get_view_data to use json_agg (preserves column order) with subquery
  (guarantees sort order is respected before aggregation)
- Fix jsonLit() for JSONB params so plain strings become valid JSON
- Update manage.py option 3 to deploy database/queries/ instead of functions.sql
- Add SPEC.md covering architecture, philosophy, and manage.py

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 22:36:53 -04:00

56 lines
1.9 KiB
PL/PgSQL

--
-- Records queries
-- All SQL for api/routes/records.js
--
SET search_path TO dataflow, public;
-- ── Read ──────────────────────────────────────────────────────────────────────
CREATE OR REPLACE FUNCTION list_records(
p_source_name TEXT,
p_limit INT DEFAULT 100,
p_offset INT DEFAULT 0,
p_transformed_only BOOLEAN DEFAULT FALSE
)
RETURNS SETOF dataflow.records AS $$
SELECT * FROM dataflow.records
WHERE source_name = p_source_name
AND (NOT p_transformed_only OR transformed IS NOT NULL)
ORDER BY id DESC
LIMIT p_limit OFFSET p_offset;
$$ LANGUAGE sql STABLE;
CREATE OR REPLACE FUNCTION get_record(p_id BIGINT)
RETURNS dataflow.records AS $$
SELECT * FROM dataflow.records WHERE id = p_id;
$$ LANGUAGE sql STABLE;
CREATE OR REPLACE FUNCTION search_records(
p_source_name TEXT,
p_query JSONB,
p_limit INT DEFAULT 100
)
RETURNS SETOF dataflow.records AS $$
SELECT * FROM dataflow.records
WHERE source_name = p_source_name
AND (data @> p_query OR transformed @> p_query)
ORDER BY id DESC
LIMIT p_limit;
$$ LANGUAGE sql STABLE;
-- ── Delete ────────────────────────────────────────────────────────────────────
CREATE OR REPLACE FUNCTION delete_record(p_id BIGINT)
RETURNS TABLE (id BIGINT) AS $$
DELETE FROM dataflow.records WHERE id = p_id RETURNING id;
$$ LANGUAGE sql;
CREATE OR REPLACE FUNCTION delete_source_records(p_source_name TEXT)
RETURNS TABLE (deleted_count BIGINT) AS $$
WITH deleted AS (
DELETE FROM dataflow.records WHERE source_name = p_source_name RETURNING id
)
SELECT count(*) AS deleted_count FROM deleted;
$$ LANGUAGE sql;