Clauses
FIELD
.field() controls which columns appear in SELECT. Three forms are accepted:
String — a single column, with optional alias:
.field('*') // all columns
.field('id') // one bare column (single-table query)
.field('post.id') // qualified column (joined query)
.field('id@postId') // aliased — default SK uses @Array — multiple columns:
.field(['id', 'title', 'author_id@authorId'])Object — the most powerful form. Keys are output aliases, values are expressions:
.field({
postId : 'post.id', // column reference
count : 42, // number literal
active : true, // boolean literal
label : "'Hello'", // string literal (single-quoted in SQL)
comments : { // aggregation → adds GROUP BY
fn : 'json_agg',
group : 'post.id',
value : { id: 'comment.id', body: 'comment.body' }
},
raw : { fn: 'raw', value: 'COALESCE(title, \'\')' }
})WHERE
.where() accepts an object where the key encodes both the column and the comparison operator. The default syntax (prefix) places the operator on the left:
| DefaultSyntaxKey | VerboseSyntaxKey | SQL produced |
|---|---|---|
column |
column |
column = $n |
=:column |
column = |
column = $n |
<>:column |
column <> |
column <> $n |
>=:column |
column >= |
column >= $n |
<=:column |
column <= |
column <= $n |
>:column |
column > |
column > $n |
<:column |
column < |
column < $n |
~~:column |
column ~~ |
column ~~ $n (LIKE) |
~~*:column |
column ~~* |
column ~~* $n (ILIKE) |
!~~:column |
column !~~ |
column !~~ $n (NOT LIKE) |
[=]:column |
{column} = |
$n = ANY(column) |
[<>]:column |
{column} <> |
$n <> ALL(column) |
[~~]:column |
{column} ~~ |
array_to_string(column,' ') ~~ $n |
&&:label |
ANDlabel |
OR group — value is an array of AND conditions |
Passing null as a value produces IS NULL / IS NOT NULL. Passing an array produces = ANY(...).
OR groups with &&::
.where({
published : true,
'&&:any' : [
{ '~~:title': '%TypeScript%' },
{ '~~:title': '%Postgres%' },
]
})
// WHERE (published = $1 AND (title ~~ $2 OR title ~~ $3))Column-to-column comparisons with col():
import { col } from 'helice';
.where({ 'post.author_id': col('user.id') })
// post.author_id = user.id (no parameter)JOIN
.join() accepts an object where the key encodes the join type and target table, and the value is the ON condition (written as if the joined table is already in scope). The default syntax (prefix) places the join type before the table name:
| DefaultSyntaxKey | VerboseSyntaxKey | SQL produced |
|---|---|---|
table |
table |
LEFT JOIN table (default) |
i#table |
INNER JOIN table |
INNER JOIN table |
f#table |
FULL JOIN table |
FULL JOIN table |
l#table |
LEFT JOIN table |
LEFT JOIN table |
r#table |
RIGHT JOIN table |
RIGHT JOIN table |
db.select('post')
.join({ user: 'id = post.author_id' }) // LEFT JOIN (default)
.join({ 'i#user': 'id = post.author_id' }) // INNER JOIN
// ... JOIN user ON user.id = post.author_idNOTE: After a join, bare column names are no longer valid — use
table.columneverywhere in.field(),.where(), and.orderBy().
ORDER BY
.orderBy() is available on SELECT. Three forms:
.orderBy('views') // single column (default ASC)
.orderBy(['published', 'views']) // multiple columns (all ASC)
.orderBy({ views: 'DESC', title: 'ASC' }) // with explicit direction
.orderBy({ views: 'DESC', title: '' }) // '' = no direction keywordAfter a join, use fully-qualified table.col notation.
RETURNING
.returning() appends a RETURNING clause to INSERT, UPDATE, and DELETE. Accepts the same string, array, and object forms as .field():
.returning('*')
.returning(['id', 'name'])
.returning({ userId: 'id', userName: 'name' })