Skip to main content

Module persistence

Module persistence 

Source
Expand description

Persistence helpers for the admin engine — basic CREATE + UPDATE.

Deliberately small. No ORM integration, no schema discovery, no migration framework. The caller hands in a (table, column → value) map and these helpers build a parameterised INSERT / UPDATE against the existing Db pool. Column names are sorted so the emitted SQL is deterministic across runs.

Functions§

bulk_delete
DELETE FROM table WHERE "id" IN (?, ?, …). Same parameter-only guarantees as bulk_update. Empty ids → no-op.
bulk_update
UPDATE table SET "<field>" = ? WHERE "id" IN (?, ?, …).
count_filtered_records
SELECT COUNT(*) counterpart of filter_records. Same WHERE shape, no ORDER BY / LIMIT / OFFSET. Feeds the page-count math.
count_records
SELECT COUNT(*) FROM "<table>". Used by the table footer to render the “Showing N of M” label and by the page header to produce the records-count subtitle.
count_search_records
SELECT COUNT(*) counterpart of search_records — same WHERE clause, no ORDER BY / LIMIT. Feeds the “Showing N of M” label when the table is in search mode.
ensure_table
Run an arbitrary CREATE TABLE IF NOT EXISTS … (or any other idempotent DDL) supplied by an AdminUiModel. Generic — every model brings its own schema string.
filter_records
Run a windowed SELECT against table combining metadata-driven filters and free-text search:
form_to_column_map
Project a FormConfig’s field values into a column → value map suitable for insert_record / update_record. The primary-key column is always skipped — the id is auto-generated on INSERT and bound separately on UPDATE.
get_record_by_id
Fetch a single row by id and return its columns as a flat column → string map. NULL becomes an empty string. Returns an empty map when no row matches — the GET handler treats that case as “fall back to the create-mode demo form” rather than surfacing an error.
insert_record
Run an INSERT INTO <table> (<cols>) VALUES (<placeholders>) against db. Returns the newly-allocated row id (last_insert_rowid()).
list_records
List rows from table, newest first, with a hard LIMIT / OFFSET window. Both bounds are bound positionally — caller values never enter the SQL text. Each row is flattened to the same column → string shape as get_record_by_id.
search_records
Case-insensitive partial match across an arbitrary list of searchable_fields. The query is lower-cased once, wrapped in %…%, and bound once per searchable field — no interpolation into the SQL text. Results are ordered newest-first and windowed by LIMIT / OFFSET, matching list_records. An empty searchable_fields slice (model declared no search columns) degrades to a normal SELECT * … ORDER BY id DESC LIMIT….
update_record
Run an UPDATE <table> SET <col = ?>... WHERE id = ? against db. The primary-key column is fixed to id for now (matches the demo table); broaden when a model needs a custom PK column.