silverbullet/website/Space Lua/Lua Integrated Query.md

111 lines
3.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

Lua Integrated Query (LIQ) is a SilverBullet specific Lua extension. It adds a convenient query syntax to the language in a backwards compatible way. It does so by overloading Luas default function call + single argument syntax when using `query` as the function call. As a result, Lua programs using LIQ are still syntactically valid Lua.
The syntax for LIQ is `query[[my query]]`. In regular Lua `[[my query]]` is just another way of writing `"my query"` (it is an alternative string syntax). Function calls that only take a string argument can omit parentheses, therefore `query[[my query]]` is equivalent to `query("my query")`.
However, in [[Space Lua]] it interpreted as an SQL (and [LINQ](https://learn.microsoft.com/en-us/dotnet/csharp/linq/))-inspired integrated query language.
General syntax:
query[[
from <var> = <expression>
where <expression>
order by <expression>
limit <expression>, <expression>
select <expression>
]]
Unlike [[Query Language]] which operates on [[Objects]] only, LIQ can operate on any Lua collection.
For instance, to sort a list of numbers in descending order:
${query[[from n = {1, 2, 3} order by n desc]]}
However, in most cases youll use it in conjunction with [[Space Lua/stdlib#tag(name)]]. Heres an example querying the 3 pages that were last modified:
${query[[
from p = tag "page"
order by p.lastModified desc
select p.name
limit 3
]]}
# Clauses
Here are the clauses that are currently supported:
## `from <expression>`
The `from` clause specifies the source of your data. There are two syntactic variants:
With explicit variable binding:
from v = <<expression>>
binding each item to the variable `v`.
And the shorter:
from <<expression>>
implicitly binding each item to the variable `_`.
Example without variable binding:
${query[[from {1, 2, 3} select _]]}
With variable binding:
${query[[from n = {1, 2, 3} select n]]}
A more realist example using `tag`:
${query[[from t = tag "page" limit 3 select t.name]]}
## `where <expression>`
The `where` clause allows you to filter data. When the expression evaluated to a truthy value, the item is included in the result.
Example:
${query[[from {1, 2, 3, 4, 5} where _ > 2]]}
Or to select all pages tagged with `#meta`:
${query[[from tag "page" where table.includes(_.tags, "meta")]]}
## `order by <expression> [desc]`
The `order by` clause allows you to sort data, when `desc` is specified it reverts the sort order.
As an example, the last 3 modified pages:
${query[[
from tag "page"
order by _.lastModified desc
select _.name
limit 3
]]}
## `limit <expression>[, <expression>]`
The `limit` clause allows you to limit the number of results, optionally with an offset.
Example:
${query[[from {1, 2, 3, 4, 5} limit 3]]}
You can also specify an offset to skip some results:
${query[[from {1, 2, 3, 4, 5} limit 3, 2]]}
## `select <expression>`
The `select` clause allows you to transform each item in the result set. If omitted, it defaults to returning the item itself.
Some examples:
Double each number:
${query[[from {1, 2, 3} select _ * 2]]}
Extract just the name from pages:
${query[[from tag "page" select _.name limit 3]]}
You can also return tables or other complex values:
${query[[
from tag "page"
select {
name = _.name,
modified = _.lastModified
}
limit 3
]]}