Bisql can generate typical index-friendly CRUD SQL from the database schema with
gen-crud.
Alongside crud.sql, Bisql also generates a sibling schema.clj file for each
table. These generated schema namespaces are currently used to attach
:malli/in and :malli/out declarations to generated CRUD queries.
tip
In practice, you will usually also want the corresponding function namespace
files, so gen-crud-and-functions is typically the more convenient command.
Depending on table structure and indexes, generated SQL commonly includes:
insertinsert-manyget-by-*listlist-by-*list-by-*-starting-withcountcount-by-*count-by-*-starting-withupdate-by-*delete-by-*upsert-by-*The generated SQL is intended to cover the repetitive queries that usually follow:
Generated *-starting-with queries are intentionally conservative:
LIKE ... ESCAPE '\'This keeps the generated queries aligned with ordinary index-friendly prefix search.
For each generated CRUD SQL file, Bisql also writes a colocated schema namespace:
src/sql/postgresql/public/users/crud.sqlsrc/sql/postgresql/public/users/schema.cljThe schema file contains table-level base schemas such as:
rowinsertupdateGenerated CRUD SQL then refers to those definitions through declaration comments
like /*:malli/in ... */ and /*:malli/out ... */, composing simple Malli
forms inline where that keeps the generated schema file smaller.
The goal is not to hide SQL. The goal is to generate the SQL you would usually write by hand anyway.
That means:
Generated upserts use PostgreSQL ON CONFLICT ... DO UPDATE.
Generated update and upsert templates now use map-shaped params:
update-by-*
:where:updatesupsert-by-*
:inserts:updatesFor example, a generated update template uses a for block in SET:
UPDATE users
SET
/*%for item in updates separating , */
/*!item.name*/created_at = /*$item.value*/CURRENT_TIMESTAMP
/*%end */
WHERE id = /*$where.id*/1
RETURNING *
This allows:
Generated upserts follow the same idea:
:inserts contains the insert path values:updates contains the conflict update assignmentsIf :updates is nil, the generated upsert renders DO NOTHING.
If :updates is an empty map, rendering still fails because an empty SET
clause is not allowed.
If you need special EXCLUDED expressions or more unusual conflict behavior,
write a custom SQL template instead.
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |