docs
This commit is contained in:
parent
34a97e2577
commit
99cd92fb4a
@ -193,6 +193,7 @@ MAX_MEMORY=16777216
|
||||
SESSION_TIME=2592000
|
||||
|
||||
HTTP_PORT=8080
|
||||
WS_BROKER_OUTBOUND_TIMEOUT_SECONDS=30
|
||||
```
|
||||
|
||||
Important settings:
|
||||
@ -204,6 +205,7 @@ Important settings:
|
||||
- `BIN_DIRECTORY` stores generated C++, wasm artifacts, compile output, and runtime caches.
|
||||
- `TMP_UPLOAD_PATH` and `SESSION_PATH` must be writable by the runtime.
|
||||
- `HTTP_PORT` is the built-in HTTP/WebSocket listener used for WebSocket upgrade traffic and direct local probes. Bind/firewall it for local access only; nginx/Apache should be the public entry point.
|
||||
- `WS_BROKER_OUTBOUND_TIMEOUT_SECONDS` controls how long a forwarded WS message can remain queued in the broker before being dropped (default `30`). Set to `0` to disable the timeout.
|
||||
- `WASM_COMPILE_SCRIPT` must point to `scripts/compile_wasm_unit` unless you provide an equivalent compiler. Relative paths are resolved from the runtime root/`COMPILER_SYS_PATH`. That script calls `scripts/check_unit_wasm.py` after linking each unit and uses the pinned WASI SDK on every deployment host.
|
||||
- `WASM_CORE_PATH` must point at the built `core.wasm` file.
|
||||
|
||||
|
||||
@ -85,6 +85,14 @@ the boundary).
|
||||
See [`docs/wasm-phase1-dvalue-abi.md`](wasm-phase1-dvalue-abi.md) for the wire
|
||||
format details.
|
||||
|
||||
Decoder robustness note: UCEB input is untrusted across the wasm membrane. The
|
||||
UCEB decoder must reject malformed magic/version/varint/length/trailing-data
|
||||
inputs and excessive nesting with explicit errors, not native or wasm traps. Its
|
||||
current hard nesting cap is intentionally low (64 levels) to stay well below the
|
||||
guest stack limit. JSON decoding follows the same rule for malformed strings and
|
||||
unicode escapes: validate bounds before every read and return an empty/partial
|
||||
`DValue` rather than reading beyond the input.
|
||||
|
||||
---
|
||||
|
||||
## 3. Units, handlers, and export naming
|
||||
@ -144,6 +152,19 @@ suspend the native SIGSEGV/SIGILL recovery handler around the wasm call so that
|
||||
Wasmtime's own trap signals are not escalated into a native fatal signal (see
|
||||
`serve_via_wasm` in `handle_complete`).
|
||||
|
||||
### Task callbacks and workspace lifetime
|
||||
|
||||
`task()` and `task_repeat()` are fork-backed. The `uce_host_task_spawn` hostcall
|
||||
captures the current `WasmWorkspace*`, but `src/lib/sys.cpp::task()` invokes the
|
||||
captured callback only in the forked child, before the hostcall stack unwinds in
|
||||
that child. The parent request may return and destroy its workspace; the child
|
||||
still has its own copy-on-write stack and its own copy of the per-request wasm
|
||||
workspace. This means a delayed task callback can run after the spawning request
|
||||
returns without dereferencing the parent's destroyed workspace. It is still a
|
||||
callback into the inherited child workspace, not a fresh normal request
|
||||
workspace; avoid adding host resources to `WasmWorkspace` that are invalid across
|
||||
`fork()` unless task callback handling is changed to birth a fresh workspace.
|
||||
|
||||
---
|
||||
|
||||
## 5. Request dispatch (`handle_complete`)
|
||||
@ -198,12 +219,14 @@ broker loop:
|
||||
a non-empty STDIN makes the FastCGI transport flush a premature response
|
||||
before `on_complete` ever runs.
|
||||
3. Connect to `/run/uce.sock` (non-blocking) and queue the encoded request in
|
||||
`ws_broker_outbound[fd]`.
|
||||
`ws_broker_outbound[fd]` with an enqueue timestamp.
|
||||
|
||||
`ws_broker_drain_outbound()` runs after every `process(50)` tick: it finishes
|
||||
writing each queued request, then drains and discards the reply (the unit's
|
||||
output comes back via the command socket, not this reply), closing the fd when
|
||||
the worker closes its end.
|
||||
the worker closes its end. If a forward remains pending beyond
|
||||
`WS_BROKER_OUTBOUND_TIMEOUT_SECONDS` (default `30`), the broker drops and
|
||||
closes it so a wedged worker cannot pin broker fds/memory indefinitely.
|
||||
|
||||
### 6.2 Outbound: `ws_*` commands flushed back to the broker
|
||||
|
||||
@ -211,8 +234,10 @@ Any unit code — not just WebSocket handlers — may call `ws_send` / `ws_send_
|
||||
/ `ws_close`. In the workspace these **record dispatch commands** rather than
|
||||
touching a socket (the workspace owns no connections); `wasm-core`'s `ws_*`
|
||||
(`src/lib/sys.cpp`) append to `websocket_dispatch_commands`, and
|
||||
`finish_response_meta` (`src/wasm/core.cpp`) emits them as `ws_commands` (plus
|
||||
`ws_connection_state` if the handler mutated per-connection state).
|
||||
`finish_response_meta` (`src/wasm/core.cpp`) emits them as `ws_commands`.
|
||||
If the handler changed per-connection state, the core also emits
|
||||
`ws_connection_state` even when no commands were emitted, and the native
|
||||
backend flushes this state-only batch to the broker.
|
||||
|
||||
`wasm_backend_serve` (`src/wasm/backend.cpp`) flushes that batch at workspace
|
||||
teardown — in **any** scenario, not just WS handlers — to the broker's command
|
||||
@ -239,9 +264,10 @@ serve_http dispatcher uses, so there is no duplicated request-forwarding code.
|
||||
handlers (it renders nothing, so it accepts every request straight through to
|
||||
`on_complete`), wires `on_complete=ws_broker_complete` and
|
||||
`on_websocket_message=ws_broker_ws_message`, listens on `HTTP_PORT` and the
|
||||
command socket, and loops `process(50)` + `drain_outbound()`. The design is
|
||||
**non-blocking outbound dispatch + async command-socket flush, all in the
|
||||
broker's single epoll loop** — the broker never blocks on a worker.
|
||||
command socket, and loops `process(50)` + `drain_outbound(timeout)`. The
|
||||
`timeout` comes from `WS_BROKER_OUTBOUND_TIMEOUT_SECONDS` (default `30`). The
|
||||
design is **non-blocking outbound dispatch + async command-socket flush, all in
|
||||
the broker's single epoll loop** — the broker never blocks on a worker.
|
||||
|
||||
The parent respawns the broker if it dies (`ws_broker_alive` / `ensure_ws_broker`
|
||||
in `main()`).
|
||||
@ -288,6 +314,7 @@ header free-functions are `inline`. The wasm backend exposes only declarations
|
||||
| `CLI_SOCKET_PATH` | `/run/uce/cli.sock` | Worker CLI socket. |
|
||||
| `HTTP_PORT` | `8080` | Raw HTTP + WebSocket port — owned by the WS broker. |
|
||||
| `WS_BROKER_SOCKET_PATH` | `/run/uce/ws-broker.sock` | Broker command socket for `ws_*` flushes. |
|
||||
| `WS_BROKER_OUTBOUND_TIMEOUT_SECONDS` | `30` | Max lifetime in seconds for queued WS broker forwards before drop. |
|
||||
| `WORKER_COUNT` | `4` | Number of uniform worker processes. |
|
||||
|
||||
---
|
||||
|
||||
@ -15,6 +15,10 @@ CLI_SOCKET_PATH=/run/uce/cli.sock
|
||||
# Keep this behind nginx/Apache on localhost or firewall it from public access.
|
||||
HTTP_PORT=8080
|
||||
|
||||
# After this many seconds, an in-flight WS broker render-forward that is still
|
||||
# not completed (including stalled writes/reads) is dropped.
|
||||
WS_BROKER_OUTBOUND_TIMEOUT_SECONDS=30
|
||||
|
||||
# OPTIONAL PROACTIVE COMPILE ROOT
|
||||
# Leave empty to scan SITE_DIRECTORY relative to the runtime root.
|
||||
PRECOMPILE_FILES_IN=
|
||||
|
||||
@ -24,9 +24,8 @@ PUBLIC_APIS = [
|
||||
("file_put_contents", True, "public"), ("file_append_contents", False, "public"),
|
||||
("cwd_get", True, "public"), ("cwd_set", True, "public"), ("process_start_directory", True, "public"),
|
||||
("file_mtime", True, "public"), ("file_unlink", True, "public"), ("expand_path", True, "public"),
|
||||
("ls", True, "public"), ("config_map_u64", True, "public"), ("config_map_f64", True, "public"),
|
||||
("config_bool_value", True, "public"), ("config_map_bool", True, "public"),
|
||||
("config_u64", True, "public"), ("config_f64", True, "public"), ("config_bool", True, "public"),
|
||||
("ls", True, "public"), ("to_u64", True, "public"), ("to_s64", True, "public"),
|
||||
("to_f64", True, "public"), ("to_bool", True, "public"),
|
||||
("request_perf", True, "public"), ("time_format_local", True, "public"),
|
||||
("time_format_relative", True, "public"), ("time_parse", True, "public"),
|
||||
("backtrace_frames_string", False, "public"), ("capture_backtrace_string", False, "public"),
|
||||
|
||||
@ -8,7 +8,7 @@ RENDER(Request& context)
|
||||
StringList routes = {"index", "dashboard", "themes", "dashboard", "workspace/projects"};
|
||||
StringList unique_routes = list_unique(routes);
|
||||
StringList sorted_routes = list_sort(unique_routes);
|
||||
StringList labels = map(sorted_routes, [](String route) { return(to_upper(replace(route, "/", " / "))); });
|
||||
StringList labels = sorted_routes.map([](String route) { return(to_upper(replace(route, "/", " / "))); });
|
||||
|
||||
DValue cards;
|
||||
DValue card;
|
||||
@ -16,9 +16,8 @@ RENDER(Request& context)
|
||||
card["title"] = "Themes"; card["section"] = "app"; card["href"] = "?themes"; cards.push(card); card.clear();
|
||||
card["title"] = "Docs"; card["section"] = "reference"; card["href"] = "../doc/index.uce"; cards.push(card);
|
||||
|
||||
DValue app_cards = dv_filter(cards, [](DValue item, String key) { return(item["section"].to_string() == "app"); });
|
||||
DValue titles = dv_map(app_cards, [](DValue item, String key) { DValue out; out = item["title"].to_string(); return(out); });
|
||||
DValue grouped = dv_group_by(cards, [](DValue item, String key) { return(item["section"].to_string()); });
|
||||
DValue app_cards = cards.filter([](DValue item, String key) { return(item["section"].to_string() == "app"); });
|
||||
DValue titles = app_cards.map([](DValue item, String key) { DValue out; out = item["title"].to_string(); return(out); });
|
||||
|
||||
<><html>
|
||||
<head>
|
||||
@ -31,7 +30,7 @@ RENDER(Request& context)
|
||||
<p>Small data-shaping helpers are useful for route lists, nav records, cards, and other render-adjacent structures.</p>
|
||||
<div class="system-info"><h3>StringList route labels</h3><pre><?= join(labels, "\n") ?></pre></div>
|
||||
<div class="system-info"><h3>DValue app card titles</h3><pre><?= json_encode(titles) ?></pre></div>
|
||||
<div class="system-info"><h3>Grouped cards</h3><pre><?= json_encode(grouped) ?></pre></div>
|
||||
<div class="system-info"><h3>All card values</h3><pre><?= json_encode(cards.values()) ?></pre></div>
|
||||
<details>
|
||||
<summary>Request Parameters</summary>
|
||||
<pre><?= var_dump(p) ?></pre>
|
||||
|
||||
@ -3,26 +3,27 @@ Types
|
||||
0_Request
|
||||
array_merge
|
||||
0_DValue
|
||||
dv_filter
|
||||
dv_group_by
|
||||
dv_keys
|
||||
dv_map
|
||||
dv_omit
|
||||
dv_pick
|
||||
dv_values
|
||||
each
|
||||
get_by_path
|
||||
has
|
||||
is_array
|
||||
is_list
|
||||
set_status
|
||||
String
|
||||
StringList
|
||||
StringMap
|
||||
2_DValue_filter
|
||||
2_DValue_keys
|
||||
2_DValue_map
|
||||
2_DValue_values
|
||||
2_DValue_each
|
||||
2_DValue_get_by_path
|
||||
2_DValue_has
|
||||
2_DValue_is_array
|
||||
2_DValue_is_list
|
||||
2_Request_set_status
|
||||
0_String
|
||||
0_StringList
|
||||
0_StringMap
|
||||
2_DValue_to_bool
|
||||
2_DValue_to_f64
|
||||
2_DValue_to_json
|
||||
2_DValue_to_s64
|
||||
2_DValue_to_string
|
||||
2_DValue_to_stringmap
|
||||
2_DValue_to_u64
|
||||
to_bool
|
||||
to_f64
|
||||
to_json
|
||||
to_s64
|
||||
to_string
|
||||
to_stringmap
|
||||
to_u64
|
||||
|
||||
@ -13,12 +13,25 @@ enum class DocPageKind
|
||||
function,
|
||||
struct_page,
|
||||
directive,
|
||||
method,
|
||||
info
|
||||
};
|
||||
|
||||
String doc_method_label(String page)
|
||||
{
|
||||
String label = page;
|
||||
nibble(label, "_");
|
||||
String class_name = nibble(label, "_");
|
||||
if(label == "")
|
||||
return(class_name);
|
||||
return(class_name + "::" + label);
|
||||
}
|
||||
|
||||
String doc_default_title(String page)
|
||||
{
|
||||
String page_title = page;
|
||||
if(page.substr(0, 2) == "2_")
|
||||
return(doc_method_label(page));
|
||||
if(page_title.length() > 1 && page_title[1] == '_')
|
||||
nibble(page_title, "_");
|
||||
return(page_title);
|
||||
@ -60,6 +73,8 @@ DocPageKind doc_page_kind(String page)
|
||||
return(DocPageKind::struct_page);
|
||||
if(page.substr(0, 2) == "1_")
|
||||
return(DocPageKind::directive);
|
||||
if(page.substr(0, 2) == "2_")
|
||||
return(DocPageKind::method);
|
||||
if(page.substr(0, 2) == "3_")
|
||||
return(DocPageKind::info);
|
||||
return(DocPageKind::function);
|
||||
@ -71,6 +86,8 @@ String doc_page_kind_badge(DocPageKind kind)
|
||||
return("struct");
|
||||
if(kind == DocPageKind::directive)
|
||||
return("directive");
|
||||
if(kind == DocPageKind::method)
|
||||
return("method");
|
||||
if(kind == DocPageKind::info)
|
||||
return("info");
|
||||
return("");
|
||||
@ -80,6 +97,8 @@ String doc_index_label(String page)
|
||||
{
|
||||
String label = page;
|
||||
auto kind = doc_page_kind(page);
|
||||
if(kind == DocPageKind::method)
|
||||
return(doc_method_label(page));
|
||||
if(kind == DocPageKind::struct_page || kind == DocPageKind::directive || kind == DocPageKind::info)
|
||||
nibble(label, "_");
|
||||
return(label);
|
||||
|
||||
@ -6,7 +6,7 @@ DValue
|
||||
|
||||
:see
|
||||
>types
|
||||
get_by_path
|
||||
2_DValue_get_by_path
|
||||
json_decode
|
||||
|
||||
:content
|
||||
@ -47,7 +47,7 @@ You will encounter `DValue` throughout the runtime, especially in:
|
||||
- `.to_bool(default)` performs best-effort boolean conversion.
|
||||
- `.to_stringmap()` converts a map-shaped tree into `StringMap`.
|
||||
|
||||
All read accessors are `const` and never modify the tree; they work directly on `const DValue&` values such as `each()` callback parameters. Every `to_*` conversion takes an optional default that is returned when the value is missing or cannot be converted — see the individual pages (`to_string`, `to_s64`, `to_u64`, `to_f64`, `to_bool`) for the exact rules:
|
||||
All read accessors are `const` and never modify the tree; they work directly on `const DValue&` values such as `each()` callback parameters. Every `to_*` conversion takes an optional default that is returned when the value is missing or cannot be converted — see the individual pages (`2_DValue_to_string`, `2_DValue_to_s64`, `2_DValue_to_u64`, `2_DValue_to_f64`, `2_DValue_to_bool`) for the exact rules:
|
||||
|
||||
```cpp
|
||||
String title = context.props["title"].to_string("Untitled");
|
||||
@ -100,7 +100,7 @@ Useful inspection helpers include:
|
||||
|
||||
## each()
|
||||
|
||||
`each(std::function<void (const DValue& t, String key)> f)` iterates over the current tree value (see the `each` page for details).
|
||||
`each(std::function<void (const DValue& t, String key)> f)` iterates over the current tree value (see `2_DValue_each` for details).
|
||||
|
||||
For map-shaped `DValue` values, the callback runs once per child entry and receives:
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ request_script_url
|
||||
request_base_url
|
||||
request_query_path
|
||||
request_query_route
|
||||
set_status
|
||||
2_Request_set_status
|
||||
component
|
||||
component_render
|
||||
unit_render
|
||||
@ -25,7 +25,7 @@ ws_connection_id
|
||||
ws_connections
|
||||
ws_send
|
||||
0_DValue
|
||||
StringMap
|
||||
0_StringMap
|
||||
UploadedFile
|
||||
|
||||
:content
|
||||
|
||||
28
site/doc/pages/0_SQLite.txt
Normal file
28
site/doc/pages/0_SQLite.txt
Normal file
@ -0,0 +1,28 @@
|
||||
:title
|
||||
SQLite
|
||||
|
||||
:sig
|
||||
SQLite
|
||||
|
||||
:see
|
||||
>types
|
||||
0_DValue
|
||||
0_StringMap
|
||||
sqlite_connect
|
||||
sqlite_query
|
||||
2_SQLite_connect
|
||||
2_SQLite_query
|
||||
2_SQLite_error
|
||||
2_SQLite_disconnect
|
||||
|
||||
:content
|
||||
SQLite connection wrapper for unit code. It opens database files, applies the runtime default pragmas, supports named parameters, and returns query rows as list-shaped `DValue` values.
|
||||
|
||||
```cpp
|
||||
SQLite db;
|
||||
if(db.connect("tmp/app.db")) {
|
||||
DValue rows = db.query("select * from notes");
|
||||
}
|
||||
```
|
||||
|
||||
Use exactly one SQL statement per `query()` call and named `:name` parameters.
|
||||
@ -1,5 +1,5 @@
|
||||
:sig
|
||||
String
|
||||
0_String
|
||||
|
||||
:see
|
||||
>types
|
||||
24
site/doc/pages/0_StringList.txt
Normal file
24
site/doc/pages/0_StringList.txt
Normal file
@ -0,0 +1,24 @@
|
||||
:title
|
||||
0_StringList
|
||||
|
||||
:sig
|
||||
0_StringList
|
||||
|
||||
:see
|
||||
>types
|
||||
0_String
|
||||
split
|
||||
join
|
||||
2_StringList_filter
|
||||
2_StringList_map
|
||||
2_StringList_keys
|
||||
2_StringList_each
|
||||
|
||||
:content
|
||||
Sequential container of `String` values. It inherits normal `std::vector<String>` behavior and adds collection helpers for filtering, mapping, indexes, and iteration.
|
||||
|
||||
```cpp
|
||||
StringList labels = split("a,b,c", ",").map([](String s) { return(to_upper(s)); });
|
||||
```
|
||||
|
||||
See the method pages for details.
|
||||
@ -1,5 +1,5 @@
|
||||
:sig
|
||||
StringMap
|
||||
0_StringMap
|
||||
|
||||
:see
|
||||
>types
|
||||
28
site/doc/pages/2_DValue_assign.txt
Normal file
28
site/doc/pages/2_DValue_assign.txt
Normal file
@ -0,0 +1,28 @@
|
||||
:title
|
||||
DValue::operator=
|
||||
|
||||
:sig
|
||||
void DValue::operator=(String v)
|
||||
void DValue::operator=(f64 v)
|
||||
void DValue::operator=(void* v)
|
||||
void DValue::operator=(DValue v)
|
||||
void DValue::operator=(StringMap v)
|
||||
|
||||
:params
|
||||
v : assigned value
|
||||
return value : none
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_set
|
||||
2_DValue_set_bool
|
||||
|
||||
:content
|
||||
Assignment overloads forward to the matching `set(...)` overloads. They are the normal concise way to write string, number, pointer, `DValue`, and `StringMap` values. Boolean values should use `set_bool()` to avoid overload ambiguity.
|
||||
|
||||
```cpp
|
||||
DValue value;
|
||||
value = "ok";
|
||||
value = 42.0;
|
||||
context.call["user"] = StringMap{{"name", "Ada"}};
|
||||
```
|
||||
16
site/doc/pages/2_DValue_clear.txt
Normal file
16
site/doc/pages/2_DValue_clear.txt
Normal file
@ -0,0 +1,16 @@
|
||||
:sig
|
||||
void DValue::clear()
|
||||
|
||||
:params
|
||||
return value : none
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_set_array
|
||||
|
||||
:content
|
||||
Clears the value into an empty map-shaped value and resets its array index. Unlike `set_array()`, this does not set list mode.
|
||||
|
||||
```cpp
|
||||
context.call["flash"].clear();
|
||||
```
|
||||
18
site/doc/pages/2_DValue_deref.txt
Normal file
18
site/doc/pages/2_DValue_deref.txt
Normal file
@ -0,0 +1,18 @@
|
||||
:sig
|
||||
DValue& DValue::deref()
|
||||
const DValue& DValue::deref() const
|
||||
|
||||
:params
|
||||
return value : referenced target when resolvable, otherwise this value
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_is_reference
|
||||
|
||||
:content
|
||||
Returns the value after following internal reference links. Most public accessors call this for you, so direct use is rare in unit code.
|
||||
|
||||
```cpp
|
||||
const DValue& actual = value.deref();
|
||||
print(actual.get_type_name());
|
||||
```
|
||||
23
site/doc/pages/2_DValue_each.txt
Normal file
23
site/doc/pages/2_DValue_each.txt
Normal file
@ -0,0 +1,23 @@
|
||||
:sig
|
||||
void DValue::each(std::function<void (const DValue& item, String key)> f) const
|
||||
|
||||
:params
|
||||
f : callback invoked for each child, or once for a scalar value
|
||||
return value : none
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_map
|
||||
2_DValue_filter
|
||||
2_DValue_is_list
|
||||
|
||||
:content
|
||||
Iterates a `DValue` without modifying it. References are dereferenced before iteration.
|
||||
|
||||
For map-shaped values, the callback receives each child and its key. List-shaped maps iterate in numeric index order (`0`, `1`, `2`, ...); ordinary maps iterate in `std::map` string-key order. Scalar values invoke the callback once with the current value and an empty key.
|
||||
|
||||
```cpp
|
||||
rows.each([&](const DValue& row, String key) {
|
||||
print(key, ": ", row.get_by_path("title").to_string("Untitled"), "\n");
|
||||
});
|
||||
```
|
||||
25
site/doc/pages/2_DValue_filter.txt
Normal file
25
site/doc/pages/2_DValue_filter.txt
Normal file
@ -0,0 +1,25 @@
|
||||
:sig
|
||||
DValue DValue::filter(StringList keys) const
|
||||
DValue DValue::filter(std::function<bool (const DValue& item, String key)> f) const
|
||||
|
||||
:params
|
||||
keys : child keys to copy when using the key-list overload
|
||||
f : predicate returning true for children to keep
|
||||
return value : filtered copy
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_map
|
||||
2_DValue_keys
|
||||
|
||||
:content
|
||||
`filter(keys)` copies existing children with the named keys into a new map-shaped `DValue`.
|
||||
|
||||
`filter(f)` calls the predicate for each item from `each()`. Kept children from list-shaped input are pushed into a new list and re-indexed from zero; kept children from map-shaped input keep their original keys. Scalar input is passed to the predicate once and, if accepted, is pushed into a list.
|
||||
|
||||
```cpp
|
||||
DValue public_user = user.filter({"name", "avatar"});
|
||||
DValue visible = items.filter([](const DValue& item, String) {
|
||||
return(!item["hidden"].to_bool());
|
||||
});
|
||||
```
|
||||
19
site/doc/pages/2_DValue_get_by_path.txt
Normal file
19
site/doc/pages/2_DValue_get_by_path.txt
Normal file
@ -0,0 +1,19 @@
|
||||
:sig
|
||||
DValue DValue::get_by_path(String path, String delim = "/") const
|
||||
|
||||
:params
|
||||
path : delimited child path to traverse
|
||||
delim : path separator string
|
||||
return value : resolved child copy, or an empty DValue when traversal fails
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_has
|
||||
2_DValue_to_string
|
||||
|
||||
:content
|
||||
Traverses nested map/list children without creating missing nodes. Empty path segments are ignored. If any segment is missing or an intermediate value is not map-shaped, the method returns an empty `DValue`.
|
||||
|
||||
```cpp
|
||||
String label = context.cfg.get_by_path("theme/options/label").to_string("Default");
|
||||
```
|
||||
18
site/doc/pages/2_DValue_get_or_create.txt
Normal file
18
site/doc/pages/2_DValue_get_or_create.txt
Normal file
@ -0,0 +1,18 @@
|
||||
:sig
|
||||
DValue* DValue::get_or_create(String s)
|
||||
|
||||
:params
|
||||
s : child key to create or return
|
||||
return value : pointer to the child node
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_key
|
||||
2_DValue_has
|
||||
|
||||
:content
|
||||
Ensures the value is map-shaped and returns the named child. If the key does not exist, an empty child is created. Creating a non-numeric key on a list-shaped value clears list mode.
|
||||
|
||||
```cpp
|
||||
payload.get_or_create("headers")->get_or_create("Content-Type")->set("text/plain");
|
||||
```
|
||||
15
site/doc/pages/2_DValue_get_type_name.txt
Normal file
15
site/doc/pages/2_DValue_get_type_name.txt
Normal file
@ -0,0 +1,15 @@
|
||||
:sig
|
||||
String DValue::get_type_name() const
|
||||
|
||||
:params
|
||||
return value : one of String, f64, bool, array, pointer, reference, or unknown
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
|
||||
:content
|
||||
Returns a human-readable name for the dereferenced value's type tag.
|
||||
|
||||
```cpp
|
||||
print(value.get_type_name());
|
||||
```
|
||||
18
site/doc/pages/2_DValue_has.txt
Normal file
18
site/doc/pages/2_DValue_has.txt
Normal file
@ -0,0 +1,18 @@
|
||||
:sig
|
||||
bool DValue::has(String s) const
|
||||
|
||||
:params
|
||||
s : child key to test
|
||||
return value : true when the dereferenced value is map-shaped and contains the key
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_key
|
||||
2_DValue_get_by_path
|
||||
|
||||
:content
|
||||
Checks for a child key without creating it. Returns false for scalars and missing keys.
|
||||
|
||||
```cpp
|
||||
if(context.props.has("title")) print(context.props["title"].to_string());
|
||||
```
|
||||
16
site/doc/pages/2_DValue_is_array.txt
Normal file
16
site/doc/pages/2_DValue_is_array.txt
Normal file
@ -0,0 +1,16 @@
|
||||
:sig
|
||||
bool DValue::is_array() const
|
||||
|
||||
:params
|
||||
return value : true when the dereferenced value is map-shaped
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_is_list
|
||||
|
||||
:content
|
||||
Returns true when the value's current type is `M`, the map/list container type. It does not require contiguous numeric keys; use `is_list()` for that.
|
||||
|
||||
```cpp
|
||||
if(payload.get_by_path("items").is_array()) { /* has children */ }
|
||||
```
|
||||
19
site/doc/pages/2_DValue_is_list.txt
Normal file
19
site/doc/pages/2_DValue_is_list.txt
Normal file
@ -0,0 +1,19 @@
|
||||
:sig
|
||||
bool DValue::is_list() const
|
||||
|
||||
:params
|
||||
return value : true when the value is an array with keys 0..n-1
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_set_array
|
||||
2_DValue_push
|
||||
|
||||
:content
|
||||
Returns true for map-shaped values that represent a list. An empty map is a list only if it was explicitly put in list mode with `set_array()` or by list operations. Non-empty lists must have canonical numeric string keys from `0` through `size - 1`.
|
||||
|
||||
```cpp
|
||||
DValue first; first = "first";
|
||||
DValue items; items.set_array(); items.push(first);
|
||||
if(items.is_list()) print(json_encode(items));
|
||||
```
|
||||
17
site/doc/pages/2_DValue_is_reference.txt
Normal file
17
site/doc/pages/2_DValue_is_reference.txt
Normal file
@ -0,0 +1,17 @@
|
||||
:sig
|
||||
bool DValue::is_reference() const
|
||||
|
||||
:params
|
||||
return value : true when this node itself is a reference node
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_reference_target
|
||||
2_DValue_deref
|
||||
|
||||
:content
|
||||
Reports whether the current node's direct type tag is the internal reference tag. Most read methods dereference automatically; this helper is mainly useful when handling reference-aware runtime state.
|
||||
|
||||
```cpp
|
||||
if(value.is_reference()) print("reference");
|
||||
```
|
||||
19
site/doc/pages/2_DValue_key.txt
Normal file
19
site/doc/pages/2_DValue_key.txt
Normal file
@ -0,0 +1,19 @@
|
||||
:sig
|
||||
DValue* DValue::key(String s)
|
||||
const DValue* DValue::key(String s) const
|
||||
|
||||
:params
|
||||
s : child key to find
|
||||
return value : pointer to existing child, or 0
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_has
|
||||
2_DValue_get_or_create
|
||||
|
||||
:content
|
||||
Looks up one child without creating it. The non-const overload forwards through references; both overloads return `0` for scalars or missing keys.
|
||||
|
||||
```cpp
|
||||
if(const DValue* user = payload.key("user")) print(user->to_json());
|
||||
```
|
||||
17
site/doc/pages/2_DValue_keys.txt
Normal file
17
site/doc/pages/2_DValue_keys.txt
Normal file
@ -0,0 +1,17 @@
|
||||
:sig
|
||||
StringList DValue::keys() const
|
||||
|
||||
:params
|
||||
return value : child keys for map/list values; empty for scalars
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_each
|
||||
0_StringList
|
||||
|
||||
:content
|
||||
Returns the keys produced by `each()`. Scalar values have no child key, so the result is empty. List-shaped values return their numeric keys as strings.
|
||||
|
||||
```cpp
|
||||
StringList names = context.props["user"].keys();
|
||||
```
|
||||
20
site/doc/pages/2_DValue_map.txt
Normal file
20
site/doc/pages/2_DValue_map.txt
Normal file
@ -0,0 +1,20 @@
|
||||
:sig
|
||||
DValue DValue::map(std::function<DValue (const DValue& item, String key)> f) const
|
||||
|
||||
:params
|
||||
f : mapper called for each iterated item
|
||||
return value : mapped copy
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_each
|
||||
2_DValue_filter
|
||||
|
||||
:content
|
||||
Builds a new `DValue` by replacing each iterated child with the mapper's returned value. List-shaped input stays list-shaped and is re-indexed by `push()`. Map-shaped input preserves keys. Scalar input is mapped once and pushed into a list.
|
||||
|
||||
```cpp
|
||||
DValue labels = rows.map([](const DValue& row, String) {
|
||||
DValue out; out = row.get_by_path("label").to_string(); return(out);
|
||||
});
|
||||
```
|
||||
22
site/doc/pages/2_DValue_operator_index.txt
Normal file
22
site/doc/pages/2_DValue_operator_index.txt
Normal file
@ -0,0 +1,22 @@
|
||||
:title
|
||||
DValue::operator[]
|
||||
|
||||
:sig
|
||||
DValue& DValue::operator[](String s)
|
||||
|
||||
:params
|
||||
s : child key to return or create
|
||||
return value : reference to the child node
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_get_or_create
|
||||
2_DValue_key
|
||||
2_DValue_has
|
||||
|
||||
:content
|
||||
Returns a mutable reference to a child, creating the child when it does not already exist. If this value is an internal reference, the operation is forwarded to the target. This has the same creation behavior as `get_or_create()`, so use `has()`, `key()`, or `get_by_path()` for non-mutating reads.
|
||||
|
||||
```cpp
|
||||
context.call["user"]["name"] = "Ada";
|
||||
```
|
||||
16
site/doc/pages/2_DValue_pop.txt
Normal file
16
site/doc/pages/2_DValue_pop.txt
Normal file
@ -0,0 +1,16 @@
|
||||
:sig
|
||||
DValue DValue::pop()
|
||||
|
||||
:params
|
||||
return value : removed child, or an empty DValue when no child exists
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_push
|
||||
|
||||
:content
|
||||
Ensures the value is map-shaped, removes the last entry according to `std::map` reverse key order, and returns it. For list-mode values, the next array index is reset to the new size.
|
||||
|
||||
```cpp
|
||||
DValue last = items.pop();
|
||||
```
|
||||
19
site/doc/pages/2_DValue_push.txt
Normal file
19
site/doc/pages/2_DValue_push.txt
Normal file
@ -0,0 +1,19 @@
|
||||
:sig
|
||||
void DValue::push(const DValue& child)
|
||||
|
||||
:params
|
||||
child : value to append/copy
|
||||
return value : none
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_pop
|
||||
2_DValue_set_array
|
||||
|
||||
:content
|
||||
Appends a child under the next numeric key. Empty values become list-shaped. Existing contiguous lists continue at their size; non-list maps use the next unused numeric key and remain non-list.
|
||||
|
||||
```cpp
|
||||
DValue first; first = "first";
|
||||
DValue list; list.set_array(); list.push(first);
|
||||
```
|
||||
18
site/doc/pages/2_DValue_reference_target.txt
Normal file
18
site/doc/pages/2_DValue_reference_target.txt
Normal file
@ -0,0 +1,18 @@
|
||||
:sig
|
||||
DValue* DValue::reference_target()
|
||||
const DValue* DValue::reference_target() const
|
||||
|
||||
:params
|
||||
return value : resolved target pointer, or 0 when this node is not a usable reference
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_is_reference
|
||||
2_DValue_deref
|
||||
|
||||
:content
|
||||
If this node is an internal reference, follows reference links up to the runtime safety limit and returns the final non-reference target. Returns `0` for non-references, null/self references, or chains that still resolve to a reference.
|
||||
|
||||
```cpp
|
||||
if(DValue* target = value.reference_target()) target->set("updated");
|
||||
```
|
||||
18
site/doc/pages/2_DValue_remove.txt
Normal file
18
site/doc/pages/2_DValue_remove.txt
Normal file
@ -0,0 +1,18 @@
|
||||
:sig
|
||||
void DValue::remove(String s)
|
||||
|
||||
:params
|
||||
s : child key to erase
|
||||
return value : none
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_clear
|
||||
2_DValue_has
|
||||
|
||||
:content
|
||||
Ensures the value is map-shaped and erases the named child. Removing the last child resets the next array index to zero.
|
||||
|
||||
```cpp
|
||||
context.call["user"].remove("password");
|
||||
```
|
||||
25
site/doc/pages/2_DValue_set.txt
Normal file
25
site/doc/pages/2_DValue_set.txt
Normal file
@ -0,0 +1,25 @@
|
||||
:sig
|
||||
void DValue::set(String s)
|
||||
void DValue::set(void* p)
|
||||
void DValue::set(f64 f)
|
||||
void DValue::set(DValue source)
|
||||
void DValue::set(StringMap source)
|
||||
|
||||
:params
|
||||
s : string value for the String overload
|
||||
p : pointer value for the pointer overload
|
||||
f : floating point value for the f64 overload
|
||||
source : DValue or StringMap to copy
|
||||
return value : none
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_set_bool
|
||||
2_DValue_set_array
|
||||
|
||||
:content
|
||||
Assigns a new value, forwarding through references when possible. String, pointer, and f64 overloads set scalar nodes. `set(DValue)` copies the source's current type and payload. `set(StringMap)` creates a map-shaped value with each string entry as a child.
|
||||
|
||||
```cpp
|
||||
DValue user; user["name"].set("Ada"); user["score"].set(9.5);
|
||||
```
|
||||
17
site/doc/pages/2_DValue_set_array.txt
Normal file
17
site/doc/pages/2_DValue_set_array.txt
Normal file
@ -0,0 +1,17 @@
|
||||
:sig
|
||||
void DValue::set_array()
|
||||
|
||||
:params
|
||||
return value : none
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_push
|
||||
2_DValue_is_list
|
||||
|
||||
:content
|
||||
Clears the value and makes it an empty list-shaped map. Subsequent `push()` calls append numeric keys starting at `0`.
|
||||
|
||||
```cpp
|
||||
DValue rows; rows.set_array(); rows.push(row);
|
||||
```
|
||||
17
site/doc/pages/2_DValue_set_bool.txt
Normal file
17
site/doc/pages/2_DValue_set_bool.txt
Normal file
@ -0,0 +1,17 @@
|
||||
:sig
|
||||
void DValue::set_bool(bool b)
|
||||
|
||||
:params
|
||||
b : boolean value to store
|
||||
return value : none
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_to_bool
|
||||
|
||||
:content
|
||||
Stores a boolean value, forwarding through references when possible.
|
||||
|
||||
```cpp
|
||||
response["ok"].set_bool(true);
|
||||
```
|
||||
17
site/doc/pages/2_DValue_set_reference.txt
Normal file
17
site/doc/pages/2_DValue_set_reference.txt
Normal file
@ -0,0 +1,17 @@
|
||||
:sig
|
||||
void DValue::set_reference(DValue* target)
|
||||
|
||||
:params
|
||||
target : target node pointer
|
||||
return value : none
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_reference_target
|
||||
|
||||
:content
|
||||
Stores an internal reference to another `DValue`. Most unit code should not need to create references directly; normal reads and writes generally follow existing references automatically.
|
||||
|
||||
```cpp
|
||||
alias.set_reference(&context.call["state"]);
|
||||
```
|
||||
20
site/doc/pages/2_DValue_set_type.txt
Normal file
20
site/doc/pages/2_DValue_set_type.txt
Normal file
@ -0,0 +1,20 @@
|
||||
:sig
|
||||
void DValue::set_type(char t)
|
||||
|
||||
:params
|
||||
t : internal type tag such as S, F, B, M, P, or R
|
||||
return value : none
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_set
|
||||
2_DValue_set_array
|
||||
|
||||
:content
|
||||
Changes the node's internal type tag, forwarding through references when possible. Switching to map type clears children, resets list state, and resets the array index.
|
||||
|
||||
Prefer the typed setters (`set`, `set_bool`, `set_array`) in normal unit code.
|
||||
|
||||
```cpp
|
||||
value.set_type('M');
|
||||
```
|
||||
17
site/doc/pages/2_DValue_to_bool.txt
Normal file
17
site/doc/pages/2_DValue_to_bool.txt
Normal file
@ -0,0 +1,17 @@
|
||||
:sig
|
||||
bool DValue::to_bool(bool default_value = false) const
|
||||
|
||||
:params
|
||||
bool : fallback returned when conversion is not possible
|
||||
return value : converted value or the fallback
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_get_by_path
|
||||
|
||||
:content
|
||||
Converts strings, numbers, bools, pointers, and maps to bool. Text such as `true`, `yes`, `on`, `1`, `false`, `no`, `off`, `0`, and `null` is recognized; non-empty unparseable strings are truthy; empty strings use the default. Multi-child maps are true when non-empty.
|
||||
|
||||
```cpp
|
||||
if(context.props["enabled"].to_bool(true)) print("enabled");
|
||||
```
|
||||
17
site/doc/pages/2_DValue_to_f64.txt
Normal file
17
site/doc/pages/2_DValue_to_f64.txt
Normal file
@ -0,0 +1,17 @@
|
||||
:sig
|
||||
f64 DValue::to_f64(f64 default_value = 0) const
|
||||
|
||||
:params
|
||||
f64 : fallback returned when conversion is not possible
|
||||
return value : converted value or the fallback
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_get_by_path
|
||||
|
||||
:content
|
||||
Converts strings, f64, bool, pointer, and single-value maps to a finite double. Invalid or empty strings return the default.
|
||||
|
||||
```cpp
|
||||
f64 price = row["price"].to_f64();
|
||||
```
|
||||
17
site/doc/pages/2_DValue_to_json.txt
Normal file
17
site/doc/pages/2_DValue_to_json.txt
Normal file
@ -0,0 +1,17 @@
|
||||
:sig
|
||||
String DValue::to_json(char quote_char = '"') const
|
||||
|
||||
:params
|
||||
quote_char : quote character passed to string escaping
|
||||
return value : JSON-ish scalar representation
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
json_encode
|
||||
|
||||
:content
|
||||
Returns the JSON scalar representation used by this low-level method: strings are escaped and quoted, numbers are emitted with `std::to_string`, bools as `true`/`false`, maps as `"(array)"`, pointers as `"(pointer)"`, and references as `"(reference)"`. For full structured encoding, use the runtime JSON helpers.
|
||||
|
||||
```cpp
|
||||
print(context.props["title"].to_json());
|
||||
```
|
||||
17
site/doc/pages/2_DValue_to_s64.txt
Normal file
17
site/doc/pages/2_DValue_to_s64.txt
Normal file
@ -0,0 +1,17 @@
|
||||
:sig
|
||||
s64 DValue::to_s64(s64 default_value = 0) const
|
||||
|
||||
:params
|
||||
s64 : fallback returned when conversion is not possible
|
||||
return value : converted value or the fallback
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_get_by_path
|
||||
|
||||
:content
|
||||
Converts strings, f64, bool, pointer, and single-value maps to a signed integer. Invalid or empty strings return the default. Values outside the signed range are clamped.
|
||||
|
||||
```cpp
|
||||
s64 count = cfg.get_by_path("limits/count").to_s64(10);
|
||||
```
|
||||
17
site/doc/pages/2_DValue_to_string.txt
Normal file
17
site/doc/pages/2_DValue_to_string.txt
Normal file
@ -0,0 +1,17 @@
|
||||
:sig
|
||||
String DValue::to_string(String default_value = "") const
|
||||
|
||||
:params
|
||||
String : fallback returned when conversion is not possible
|
||||
return value : converted value or the fallback
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_get_by_path
|
||||
|
||||
:content
|
||||
Returns the stored string, converts f64/bool/pointer values to text, and returns the default for empty strings, maps, unresolved references, or unknown types. Bool text is `(true)` or `(false)`.
|
||||
|
||||
```cpp
|
||||
String title = row["title"].to_string("Untitled");
|
||||
```
|
||||
17
site/doc/pages/2_DValue_to_stringmap.txt
Normal file
17
site/doc/pages/2_DValue_to_stringmap.txt
Normal file
@ -0,0 +1,17 @@
|
||||
:sig
|
||||
StringMap DValue::to_stringmap() const
|
||||
|
||||
:params
|
||||
return value : StringMap copy of the value
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
0_StringMap
|
||||
2_DValue_to_string
|
||||
|
||||
:content
|
||||
Converts a `DValue` to `StringMap`. Map children become entries converted with `to_string()`. Non-empty strings become `value=<string>`. f64, bool, and pointer values become `value=<to_string()>`. References that cannot be resolved produce an empty map.
|
||||
|
||||
```cpp
|
||||
StringMap headers = context.call["headers"].to_stringmap();
|
||||
```
|
||||
17
site/doc/pages/2_DValue_to_u64.txt
Normal file
17
site/doc/pages/2_DValue_to_u64.txt
Normal file
@ -0,0 +1,17 @@
|
||||
:sig
|
||||
u64 DValue::to_u64(u64 default_value = 0) const
|
||||
|
||||
:params
|
||||
u64 : fallback returned when conversion is not possible
|
||||
return value : converted value or the fallback
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_get_by_path
|
||||
|
||||
:content
|
||||
Converts strings, f64, bool, pointer, and single-value maps to an unsigned integer. Invalid or empty strings return the default. Negative values clamp to zero and oversized values clamp to `u64` max.
|
||||
|
||||
```cpp
|
||||
u64 id = row["id"].to_u64();
|
||||
```
|
||||
19
site/doc/pages/2_DValue_values.txt
Normal file
19
site/doc/pages/2_DValue_values.txt
Normal file
@ -0,0 +1,19 @@
|
||||
:sig
|
||||
DValue DValue::values() const
|
||||
|
||||
:params
|
||||
return value : a list-shaped DValue containing each iterated child value
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
2_DValue_each
|
||||
2_DValue_push
|
||||
|
||||
:content
|
||||
Copies the values produced by `each()` into a new list-shaped `DValue`.
|
||||
|
||||
```cpp
|
||||
DValue titles = articles.map([](const DValue& row, String) {
|
||||
DValue v; v = row.get_by_path("title").to_string(); return(v);
|
||||
}).values();
|
||||
```
|
||||
18
site/doc/pages/2_Request_ob_start.txt
Normal file
18
site/doc/pages/2_Request_ob_start.txt
Normal file
@ -0,0 +1,18 @@
|
||||
:sig
|
||||
void Request::ob_start()
|
||||
|
||||
:params
|
||||
return value : none
|
||||
|
||||
:see
|
||||
0_Request
|
||||
ob_start
|
||||
ob_get_close
|
||||
|
||||
:content
|
||||
Starts a new output buffer for the request and makes it the active `context.ob`. Most unit code should prefer the higher-level output-buffer helpers (`ob_start()`, `ob_get()`, `ob_get_close()`, `ob_close()`) rather than calling the method directly.
|
||||
|
||||
```cpp
|
||||
context.ob_start();
|
||||
print("captured");
|
||||
```
|
||||
19
site/doc/pages/2_Request_set_status.txt
Normal file
19
site/doc/pages/2_Request_set_status.txt
Normal file
@ -0,0 +1,19 @@
|
||||
:sig
|
||||
void Request::set_status(s32 code, String reason = "")
|
||||
|
||||
:params
|
||||
code : HTTP status code
|
||||
reason : optional reason phrase override
|
||||
return value : none
|
||||
|
||||
:see
|
||||
0_Request
|
||||
redirect
|
||||
set_cookie
|
||||
|
||||
:content
|
||||
Sets the request status line and mirrors the numeric status into `context.flags.status`. When `reason` is omitted, common HTTP status codes get their standard phrase. FastCGI-style requests use a `Status:` prefix; other requests use `HTTP/1.1`.
|
||||
|
||||
```cpp
|
||||
context.set_status(404, "Not Found");
|
||||
```
|
||||
18
site/doc/pages/2_SQLite_connect.txt
Normal file
18
site/doc/pages/2_SQLite_connect.txt
Normal file
@ -0,0 +1,18 @@
|
||||
:sig
|
||||
bool SQLite::connect(String path)
|
||||
|
||||
:params
|
||||
path : database file path
|
||||
return value : true when the database opens and default pragmas apply
|
||||
|
||||
:see
|
||||
0_SQLite
|
||||
2_SQLite_error
|
||||
2_SQLite_disconnect
|
||||
|
||||
:content
|
||||
Opens or creates a SQLite database, registers the wrapper for request cleanup, sets a busy timeout, and applies default pragmas (`foreign_keys=ON`, WAL journal mode, synchronous NORMAL). On failure, details are available through `error()`.
|
||||
|
||||
```cpp
|
||||
SQLite db; if(!db.connect("tmp/app.db")) print(db.error());
|
||||
```
|
||||
15
site/doc/pages/2_SQLite_disconnect.txt
Normal file
15
site/doc/pages/2_SQLite_disconnect.txt
Normal file
@ -0,0 +1,15 @@
|
||||
:sig
|
||||
void SQLite::disconnect()
|
||||
|
||||
:params
|
||||
return value : none
|
||||
|
||||
:see
|
||||
0_SQLite
|
||||
|
||||
:content
|
||||
Forgets any worker-cache entry for this wrapper, closes the SQLite connection if open, clears the connection pointer, and unregisters it from request cleanup.
|
||||
|
||||
```cpp
|
||||
db.disconnect();
|
||||
```
|
||||
16
site/doc/pages/2_SQLite_error.txt
Normal file
16
site/doc/pages/2_SQLite_error.txt
Normal file
@ -0,0 +1,16 @@
|
||||
:sig
|
||||
String SQLite::error()
|
||||
|
||||
:params
|
||||
return value : current statement/connection error text, or an empty string
|
||||
|
||||
:see
|
||||
0_SQLite
|
||||
|
||||
:content
|
||||
Returns stored statement information when present; otherwise returns SQLite's current connection error message when connected.
|
||||
|
||||
```cpp
|
||||
DValue rows = db.query("select * from missing");
|
||||
print(db.error());
|
||||
```
|
||||
19
site/doc/pages/2_SQLite_query.txt
Normal file
19
site/doc/pages/2_SQLite_query.txt
Normal file
@ -0,0 +1,19 @@
|
||||
:sig
|
||||
DValue SQLite::query(String q)
|
||||
DValue SQLite::query(String q, const StringMap& params)
|
||||
|
||||
:params
|
||||
q : exactly one SQL statement
|
||||
params : named :name parameter values; missing keys bind NULL
|
||||
return value : result rows as a list-shaped DValue, or empty on error/non-row statements
|
||||
|
||||
:see
|
||||
0_SQLite
|
||||
2_SQLite_error
|
||||
|
||||
:content
|
||||
Prepares and runs exactly one SQL statement. Extra trailing SQL statements are rejected. Parameters must be named `:name` placeholders; positional `?` placeholders are rejected. Result rows are returned as a list of maps keyed by column name. Integer, float, text, blob, and null column types map to matching `DValue` representations where null leaves the field empty. After completion, `affected_rows`, `insert_id`, and `statement_info` are updated.
|
||||
|
||||
```cpp
|
||||
DValue rows = db.query("select * from users where id=:id", {{"id", "42"}});
|
||||
```
|
||||
16
site/doc/pages/2_StringList_each.txt
Normal file
16
site/doc/pages/2_StringList_each.txt
Normal file
@ -0,0 +1,16 @@
|
||||
:sig
|
||||
template<typename F> void StringList::each(F f) const
|
||||
|
||||
:params
|
||||
f : callback called with each String
|
||||
return value : none
|
||||
|
||||
:see
|
||||
0_StringList
|
||||
|
||||
:content
|
||||
Calls the callback once for each string in order.
|
||||
|
||||
```cpp
|
||||
items.each([](String item) { print(item, "\n"); });
|
||||
```
|
||||
17
site/doc/pages/2_StringList_filter.txt
Normal file
17
site/doc/pages/2_StringList_filter.txt
Normal file
@ -0,0 +1,17 @@
|
||||
:sig
|
||||
template<typename F> StringList StringList::filter(F f) const
|
||||
|
||||
:params
|
||||
f : predicate called with each String
|
||||
return value : new list containing items where f(item) is true
|
||||
|
||||
:see
|
||||
0_StringList
|
||||
2_StringList_map
|
||||
|
||||
:content
|
||||
Returns a new `StringList` containing the original items for which the predicate returns true. Order is preserved.
|
||||
|
||||
```cpp
|
||||
StringList routes = split("home admin", " ").filter([](String s) { return(s != "admin"); });
|
||||
```
|
||||
15
site/doc/pages/2_StringList_keys.txt
Normal file
15
site/doc/pages/2_StringList_keys.txt
Normal file
@ -0,0 +1,15 @@
|
||||
:sig
|
||||
StringList StringList::keys() const
|
||||
|
||||
:params
|
||||
return value : index keys as strings
|
||||
|
||||
:see
|
||||
0_StringList
|
||||
|
||||
:content
|
||||
Returns the list indexes as strings from `0` through `size() - 1`.
|
||||
|
||||
```cpp
|
||||
StringList keys = items.keys(); // {"0", "1", ...}
|
||||
```
|
||||
17
site/doc/pages/2_StringList_map.txt
Normal file
17
site/doc/pages/2_StringList_map.txt
Normal file
@ -0,0 +1,17 @@
|
||||
:sig
|
||||
template<typename F> StringList StringList::map(F f) const
|
||||
|
||||
:params
|
||||
f : mapper called with each String
|
||||
return value : new list of mapped strings
|
||||
|
||||
:see
|
||||
0_StringList
|
||||
2_StringList_filter
|
||||
|
||||
:content
|
||||
Returns a new `StringList` containing the mapper result for each item, in the same order.
|
||||
|
||||
```cpp
|
||||
StringList upper = names.map([](String s) { return(to_upper(s)); });
|
||||
```
|
||||
@ -1,25 +0,0 @@
|
||||
:sig
|
||||
StringList
|
||||
|
||||
:see
|
||||
>types
|
||||
String
|
||||
split
|
||||
split_space
|
||||
split_utf8
|
||||
join
|
||||
regex_split
|
||||
|
||||
:content
|
||||
Sequential container of `String` values.
|
||||
|
||||
`StringList` is an alias for `std::vector<String>`.
|
||||
|
||||
It is returned by split-style helpers such as `split()`, `split_space()`, `split_utf8()`, and `regex_split()`.
|
||||
|
||||
Use `join()` when you want to turn a `StringList` back into a single `String`.
|
||||
|
||||
Related:
|
||||
|
||||
- PHP: indexed arrays of strings
|
||||
- JavaScript / Node.js: arrays of strings
|
||||
@ -10,7 +10,7 @@ return value : merged result
|
||||
:see
|
||||
>types
|
||||
0_DValue
|
||||
StringMap
|
||||
0_StringMap
|
||||
json_decode
|
||||
|
||||
:content
|
||||
|
||||
@ -12,7 +12,8 @@ unit_render
|
||||
3_C++ Preprocessor
|
||||
map
|
||||
filter
|
||||
dv_filter
|
||||
2_DValue_filter
|
||||
2_DValue_map
|
||||
|
||||
:content
|
||||
UCE is server-first C++ with a small template preprocessor. It does not try to be React, but several concepts map cleanly.
|
||||
@ -45,10 +46,10 @@ That keeps file-based and hierarchical routing in normal UCE code instead of hid
|
||||
The function library includes small collection helpers for common route/menu/card transformations:
|
||||
|
||||
```cpp
|
||||
auto visible = filter(routes, [](String route) { return(route != "admin"); });
|
||||
auto labels = map(visible, [](String route) { return(to_upper(route)); });
|
||||
DValue app_items = dv_filter(menu, [](DValue item, String key) { return(item["section"].to_string() == "app"); });
|
||||
DValue by_section = dv_group_by(menu, [](DValue item, String key) { return(item["section"].to_string()); });
|
||||
auto visible = routes.filter([](String route) { return(route != "admin"); });
|
||||
auto labels = visible.map([](String route) { return(to_upper(route)); });
|
||||
DValue app_items = menu.filter([](DValue item, String key) { return(item["section"].to_string() == "app"); });
|
||||
DValue labels_by_key = menu.map([](DValue item, String key) { DValue out; out = item["label"].to_string(); return(out); });
|
||||
```
|
||||
|
||||
Use these when a short transformation is clearer than a loop. Prefer explicit loops for side effects or multi-step validation.
|
||||
|
||||
@ -1,13 +0,0 @@
|
||||
:sig
|
||||
bool config_bool(String key, bool fallback = true)
|
||||
|
||||
:params
|
||||
key : server configuration key
|
||||
fallback : value returned when missing
|
||||
|
||||
:see
|
||||
>sys
|
||||
>config_bool_value
|
||||
|
||||
:content
|
||||
Reads a boolean value from the active server configuration.
|
||||
@ -1,13 +0,0 @@
|
||||
:sig
|
||||
bool config_bool_value(String raw, bool fallback = true)
|
||||
|
||||
:params
|
||||
raw : raw string value
|
||||
fallback : value returned for an empty string
|
||||
|
||||
:see
|
||||
>sys
|
||||
>config_bool
|
||||
|
||||
:content
|
||||
Parses common configuration booleans. Empty uses the fallback; `0`, `false`, `no`, and `off` are false; other non-empty values are true.
|
||||
@ -1,13 +0,0 @@
|
||||
:sig
|
||||
f64 config_f64(String key, f64 fallback)
|
||||
|
||||
:params
|
||||
key : server configuration key
|
||||
fallback : value returned when missing or invalid
|
||||
|
||||
:see
|
||||
>sys
|
||||
>config_map_f64
|
||||
|
||||
:content
|
||||
Reads a floating-point value from the active server configuration.
|
||||
@ -1,14 +0,0 @@
|
||||
:sig
|
||||
bool config_map_bool(StringMap& cfg, String key, bool fallback = true)
|
||||
|
||||
:params
|
||||
cfg : configuration map
|
||||
key : entry to parse
|
||||
fallback : value returned when missing
|
||||
|
||||
:see
|
||||
>sys
|
||||
>config_bool_value
|
||||
|
||||
:content
|
||||
Reads a boolean from a string map using `config_bool_value()` semantics.
|
||||
@ -1,14 +0,0 @@
|
||||
:sig
|
||||
f64 config_map_f64(StringMap& cfg, String key, f64 fallback)
|
||||
|
||||
:params
|
||||
cfg : configuration map
|
||||
key : entry to parse
|
||||
fallback : value returned when missing or invalid
|
||||
|
||||
:see
|
||||
>sys
|
||||
>config_f64
|
||||
|
||||
:content
|
||||
Reads a floating-point value from a string map with fallback handling.
|
||||
@ -1,14 +0,0 @@
|
||||
:sig
|
||||
u64 config_map_u64(StringMap& cfg, String key, u64 fallback)
|
||||
|
||||
:params
|
||||
cfg : configuration map
|
||||
key : entry to parse
|
||||
fallback : value returned when missing or invalid
|
||||
|
||||
:see
|
||||
>sys
|
||||
>config_u64
|
||||
|
||||
:content
|
||||
Reads an unsigned integer from a string map with fallback handling.
|
||||
@ -1,13 +0,0 @@
|
||||
:sig
|
||||
u64 config_u64(String key, u64 fallback)
|
||||
|
||||
:params
|
||||
key : server configuration key
|
||||
fallback : value returned when missing or invalid
|
||||
|
||||
:see
|
||||
>sys
|
||||
>config_map_u64
|
||||
|
||||
:content
|
||||
Reads an unsigned integer from the active server configuration.
|
||||
@ -1,26 +0,0 @@
|
||||
:title
|
||||
dv_filter
|
||||
|
||||
:sig
|
||||
DValue dv_filter(DValue tree, function<bool (DValue, String)> f)
|
||||
|
||||
:see
|
||||
StringList
|
||||
0_DValue
|
||||
filter
|
||||
|
||||
:content
|
||||
Keeps children for which f returns true. List-like input stays list-like.
|
||||
|
||||
These helpers keep common data-shaping code close to render code, routers, and configuration trees. They are useful for route lists, navigation items, cards, and records that need simple transformations before rendering.
|
||||
|
||||
```cpp
|
||||
DValue visible = dv_filter(items, [](DValue item, String key) { return(item["hidden"].to_bool() == false); });
|
||||
```
|
||||
|
||||
Prefer these helpers over open-coded loops when the transformation itself is the important part of the code. Use an explicit loop when mutation, error handling, or side effects are the main concern.
|
||||
|
||||
## Related Concepts
|
||||
|
||||
- JavaScript / React: `Array.map`, `Array.filter`, `Array.find`, object `pick`/`omit`, and grouping route or navigation records before rendering.
|
||||
- PHP: `array_map`, `array_filter`, `array_unique`, and associative array projection.
|
||||
@ -1,26 +0,0 @@
|
||||
:title
|
||||
dv_group_by
|
||||
|
||||
:sig
|
||||
DValue dv_group_by(DValue tree, function<String (DValue, String)> f)
|
||||
|
||||
:see
|
||||
StringList
|
||||
0_DValue
|
||||
filter
|
||||
|
||||
:content
|
||||
Groups children into list-like buckets by the string returned from f.
|
||||
|
||||
These helpers keep common data-shaping code close to render code, routers, and configuration trees. They are useful for route lists, navigation items, cards, and records that need simple transformations before rendering.
|
||||
|
||||
```cpp
|
||||
DValue by_section = dv_group_by(menu, [](DValue item, String key) { return(item["section"].to_string()); });
|
||||
```
|
||||
|
||||
Prefer these helpers over open-coded loops when the transformation itself is the important part of the code. Use an explicit loop when mutation, error handling, or side effects are the main concern.
|
||||
|
||||
## Related Concepts
|
||||
|
||||
- JavaScript / React: `Array.map`, `Array.filter`, `Array.find`, object `pick`/`omit`, and grouping route or navigation records before rendering.
|
||||
- PHP: `array_map`, `array_filter`, `array_unique`, and associative array projection.
|
||||
@ -1,26 +0,0 @@
|
||||
:title
|
||||
dv_keys
|
||||
|
||||
:sig
|
||||
StringList dv_keys(DValue tree)
|
||||
|
||||
:see
|
||||
StringList
|
||||
0_DValue
|
||||
filter
|
||||
|
||||
:content
|
||||
Returns map keys from a DValue. Scalar values produce an empty list.
|
||||
|
||||
These helpers keep common data-shaping code close to render code, routers, and configuration trees. They are useful for route lists, navigation items, cards, and records that need simple transformations before rendering.
|
||||
|
||||
```cpp
|
||||
StringList keys = dv_keys(context.cfg["menu"]);
|
||||
```
|
||||
|
||||
Prefer these helpers over open-coded loops when the transformation itself is the important part of the code. Use an explicit loop when mutation, error handling, or side effects are the main concern.
|
||||
|
||||
## Related Concepts
|
||||
|
||||
- JavaScript / React: `Array.map`, `Array.filter`, `Array.find`, object `pick`/`omit`, and grouping route or navigation records before rendering.
|
||||
- PHP: `array_map`, `array_filter`, `array_unique`, and associative array projection.
|
||||
@ -1,26 +0,0 @@
|
||||
:title
|
||||
dv_map
|
||||
|
||||
:sig
|
||||
DValue dv_map(DValue tree, function<DValue (DValue, String)> f)
|
||||
|
||||
:see
|
||||
StringList
|
||||
0_DValue
|
||||
filter
|
||||
|
||||
:content
|
||||
Transforms each child. List-like input stays list-like; map input keeps keys.
|
||||
|
||||
These helpers keep common data-shaping code close to render code, routers, and configuration trees. They are useful for route lists, navigation items, cards, and records that need simple transformations before rendering.
|
||||
|
||||
```cpp
|
||||
DValue titles = dv_map(items, [](DValue item, String key) { DValue out; out = item["title"].to_string(); return(out); });
|
||||
```
|
||||
|
||||
Prefer these helpers over open-coded loops when the transformation itself is the important part of the code. Use an explicit loop when mutation, error handling, or side effects are the main concern.
|
||||
|
||||
## Related Concepts
|
||||
|
||||
- JavaScript / React: `Array.map`, `Array.filter`, `Array.find`, object `pick`/`omit`, and grouping route or navigation records before rendering.
|
||||
- PHP: `array_map`, `array_filter`, `array_unique`, and associative array projection.
|
||||
@ -1,26 +0,0 @@
|
||||
:title
|
||||
dv_omit
|
||||
|
||||
:sig
|
||||
DValue dv_omit(DValue tree, StringList keys)
|
||||
|
||||
:see
|
||||
StringList
|
||||
0_DValue
|
||||
filter
|
||||
|
||||
:content
|
||||
Copies a DValue map except for selected keys.
|
||||
|
||||
These helpers keep common data-shaping code close to render code, routers, and configuration trees. They are useful for route lists, navigation items, cards, and records that need simple transformations before rendering.
|
||||
|
||||
```cpp
|
||||
DValue safe_user = dv_omit(user, {"password_hash"});
|
||||
```
|
||||
|
||||
Prefer these helpers over open-coded loops when the transformation itself is the important part of the code. Use an explicit loop when mutation, error handling, or side effects are the main concern.
|
||||
|
||||
## Related Concepts
|
||||
|
||||
- JavaScript / React: `Array.map`, `Array.filter`, `Array.find`, object `pick`/`omit`, and grouping route or navigation records before rendering.
|
||||
- PHP: `array_map`, `array_filter`, `array_unique`, and associative array projection.
|
||||
@ -1,26 +0,0 @@
|
||||
:title
|
||||
dv_pick
|
||||
|
||||
:sig
|
||||
DValue dv_pick(DValue tree, StringList keys)
|
||||
|
||||
:see
|
||||
StringList
|
||||
0_DValue
|
||||
filter
|
||||
|
||||
:content
|
||||
Copies only selected keys from a DValue map.
|
||||
|
||||
These helpers keep common data-shaping code close to render code, routers, and configuration trees. They are useful for route lists, navigation items, cards, and records that need simple transformations before rendering.
|
||||
|
||||
```cpp
|
||||
DValue public_user = dv_pick(user, {"name", "avatar"});
|
||||
```
|
||||
|
||||
Prefer these helpers over open-coded loops when the transformation itself is the important part of the code. Use an explicit loop when mutation, error handling, or side effects are the main concern.
|
||||
|
||||
## Related Concepts
|
||||
|
||||
- JavaScript / React: `Array.map`, `Array.filter`, `Array.find`, object `pick`/`omit`, and grouping route or navigation records before rendering.
|
||||
- PHP: `array_map`, `array_filter`, `array_unique`, and associative array projection.
|
||||
@ -1,26 +0,0 @@
|
||||
:title
|
||||
dv_values
|
||||
|
||||
:sig
|
||||
DValue dv_values(DValue tree)
|
||||
|
||||
:see
|
||||
StringList
|
||||
0_DValue
|
||||
filter
|
||||
|
||||
:content
|
||||
Returns child values as a list-like DValue.
|
||||
|
||||
These helpers keep common data-shaping code close to render code, routers, and configuration trees. They are useful for route lists, navigation items, cards, and records that need simple transformations before rendering.
|
||||
|
||||
```cpp
|
||||
DValue menu_items = dv_values(context.cfg["menu"]);
|
||||
```
|
||||
|
||||
Prefer these helpers over open-coded loops when the transformation itself is the important part of the code. Use an explicit loop when mutation, error handling, or side effects are the main concern.
|
||||
|
||||
## Related Concepts
|
||||
|
||||
- JavaScript / React: `Array.map`, `Array.filter`, `Array.find`, object `pick`/`omit`, and grouping route or navigation records before rendering.
|
||||
- PHP: `array_map`, `array_filter`, `array_unique`, and associative array projection.
|
||||
@ -1,36 +0,0 @@
|
||||
:sig
|
||||
void DValue::each(function<void (const DValue& item, String key)> f) const
|
||||
|
||||
:params
|
||||
f : callback invoked per child with the child node and its key
|
||||
return value : none
|
||||
|
||||
:see
|
||||
>types
|
||||
0_DValue
|
||||
dv_map
|
||||
dv_filter
|
||||
dv_keys
|
||||
is_list
|
||||
|
||||
:content
|
||||
Iterates a `DValue`. This is a read accessor: it is `const`, never creates or modifies nodes, and dereferences internal references automatically.
|
||||
|
||||
For map-shaped nodes the callback runs once per child, in key order, receiving the child and its key. For scalar nodes it runs exactly once with the node itself and an empty key.
|
||||
|
||||
The callback receives the child as `const DValue&` — no copy is made, and all read accessors (`to_string()`, `to_s64()`, `get_by_path()`, ...) work on it directly:
|
||||
|
||||
```cpp
|
||||
rows.each([&](const DValue& row, String key) {
|
||||
out("<li>", html_escape(row.get_by_path("title").to_string("Untitled")), "</li>");
|
||||
});
|
||||
```
|
||||
|
||||
Declaring the callback parameter as plain `DValue` also works but deep-copies every child; prefer `const DValue&`. To transform or filter into a new tree, use `dv_map()` / `dv_filter()` instead of mutating inside the callback.
|
||||
|
||||
List-shaped trees (see `is_list`) iterate in numeric index order, matching `json_encode()` and the other serializers. Keyed maps iterate in string key order.
|
||||
|
||||
## Related Concepts
|
||||
|
||||
- PHP: `foreach ($tree as $key => $item)`
|
||||
- JavaScript: `Object.entries(obj).forEach(([key, item]) => ...)`
|
||||
@ -15,7 +15,7 @@ page_runtime_error : UCE page rendered (status 500) after a recovered fault or u
|
||||
>runtime
|
||||
0_Request
|
||||
0_DValue
|
||||
set_status
|
||||
2_Request_set_status
|
||||
|
||||
:content
|
||||
Three optional keys in `/etc/uce/settings.cfg` route error conditions to developer-defined UCE pages. Each key names a `.uce` file, either absolute or relative to the server's working directory. When a key is unset, or the named file does not exist, or the error page itself fails, the runtime's built-in plain-text behavior stands.
|
||||
|
||||
@ -8,7 +8,7 @@ return value : a f64 containing the number (0 if no number could be identified).
|
||||
:see
|
||||
>string
|
||||
int_val
|
||||
String
|
||||
0_String
|
||||
|
||||
:content
|
||||
Extracts a floating point number from a `String`.
|
||||
|
||||
@ -1,34 +0,0 @@
|
||||
:sig
|
||||
DValue DValue::get_by_path(String path, String delim = "/") const
|
||||
|
||||
:params
|
||||
path : slash-delimited path to traverse
|
||||
delim : optional path separator
|
||||
return value : the resolved child node, or an empty `DValue` when the path cannot be followed
|
||||
|
||||
:see
|
||||
0_DValue
|
||||
0_Request
|
||||
>types
|
||||
json_decode
|
||||
has
|
||||
to_string
|
||||
|
||||
:content
|
||||
Traverses a nested `DValue` without creating missing keys. This is a read accessor: it is `const` and never modifies the tree, unlike `operator[]`, which creates missing entries.
|
||||
|
||||
Empty path segments are ignored, so leading and trailing `/` characters are harmless. If any intermediate node is not a map or a segment is missing, `get_by_path()` returns an empty `DValue`.
|
||||
|
||||
A missing path therefore reads like an empty value — combine it with the `to_*` default arguments to express a fallback in one call:
|
||||
|
||||
## Example
|
||||
|
||||
```cpp
|
||||
String label = context.cfg.get_by_path("theme/options/portal-dark/label").to_string("Portal Dark");
|
||||
s64 page_size = context.cfg.get_by_path("app/page_size").to_s64(25);
|
||||
```
|
||||
|
||||
## Related Concepts
|
||||
|
||||
- PHP: deep array access helpers for associative arrays, decoded JSON, or configuration trees
|
||||
- JavaScript / Node.js: optional chaining like `obj?.a?.b`, lodash `get`, or small path-walking helpers
|
||||
@ -1,36 +0,0 @@
|
||||
:sig
|
||||
bool DValue::has(String s) const
|
||||
|
||||
:params
|
||||
s : child key to test
|
||||
return value : true when the node is map-shaped and contains the key
|
||||
|
||||
:see
|
||||
>types
|
||||
0_DValue
|
||||
get_by_path
|
||||
each
|
||||
is_array
|
||||
|
||||
:content
|
||||
Tests whether a map-shaped `DValue` contains a child key, without creating it. This is a read accessor: it is `const`, never creates or modifies nodes, and dereferences internal references automatically.
|
||||
|
||||
Returns `false` for scalar nodes and for missing keys.
|
||||
|
||||
This matters because `operator[]` creates missing entries, exactly like `std::map`. Use `has()` (or `get_by_path()`) when you only want to look:
|
||||
|
||||
```cpp
|
||||
if(context.props.has("avatar"))
|
||||
print(component("components/basic/avatar", context.props["avatar"], context));
|
||||
```
|
||||
|
||||
`has()` only checks one level. For nested checks, combine with `get_by_path()`:
|
||||
|
||||
```cpp
|
||||
bool configured = context.cfg.get_by_path("mail/smtp").is_array();
|
||||
```
|
||||
|
||||
## Related Concepts
|
||||
|
||||
- PHP: `array_key_exists()` / `isset()`
|
||||
- JavaScript: `Object.hasOwn(obj, key)` / `key in obj`
|
||||
@ -9,7 +9,7 @@ return value : a u64 containing the number (0 if no number could be identified).
|
||||
:see
|
||||
>string
|
||||
float_val
|
||||
String
|
||||
0_String
|
||||
|
||||
:content
|
||||
Extracts an integer value from `s`.
|
||||
|
||||
@ -1,34 +0,0 @@
|
||||
:sig
|
||||
bool DValue::is_array() const
|
||||
|
||||
:params
|
||||
return value : true when the node is map-shaped
|
||||
|
||||
:see
|
||||
>types
|
||||
0_DValue
|
||||
is_list
|
||||
has
|
||||
each
|
||||
|
||||
:content
|
||||
Tests whether a `DValue` node is map-shaped, i.e. holds nested child values rather than a scalar. This is a read accessor: it is `const`, never creates or modifies nodes, and dereferences internal references automatically.
|
||||
|
||||
`is_array()` is true for both list-like and keyed containers; use `is_list()` to distinguish the two:
|
||||
|
||||
```cpp
|
||||
DValue rows = sqlite_query(db, "select * from notes");
|
||||
if(rows.is_array())
|
||||
{
|
||||
rows.each([&](const DValue& row, String key) {
|
||||
// ...
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
Scalar values (strings, numbers, booleans, pointers) return `false`, as do unresolvable references.
|
||||
|
||||
## Related Concepts
|
||||
|
||||
- PHP: `is_array()`
|
||||
- JavaScript: `typeof value === "object"`
|
||||
@ -1,35 +0,0 @@
|
||||
:sig
|
||||
bool DValue::is_list() const
|
||||
|
||||
:params
|
||||
return value : true when the node is a sequential, numerically indexed container
|
||||
|
||||
:see
|
||||
>types
|
||||
0_DValue
|
||||
is_array
|
||||
push
|
||||
each
|
||||
dv_values
|
||||
|
||||
:content
|
||||
Tests whether a map-shaped `DValue` represents a list: its keys are the numeric strings `"0"`, `"1"`, `"2"`, ... in unbroken sequence. This is a read accessor: it is `const`, never creates or modifies nodes, and dereferences internal references automatically.
|
||||
|
||||
Containers built with `push()` are lists. An empty container counts as a list when it was created with `set_array()` or `push()`; a keyed map (or a map with gaps in its numeric keys) is `is_array()` but not `is_list()`.
|
||||
|
||||
```cpp
|
||||
DValue items;
|
||||
items.push(first_item);
|
||||
items.push(second_item);
|
||||
// items.is_list() == true
|
||||
|
||||
items["custom"] = "x";
|
||||
// items.is_list() == false, items.is_array() == true
|
||||
```
|
||||
|
||||
`dv_map()` and `dv_filter()` use this distinction: list inputs re-index from zero, while map inputs keep their original keys.
|
||||
|
||||
## Related Concepts
|
||||
|
||||
- PHP: `array_is_list()`
|
||||
- JavaScript: `Array.isArray()`
|
||||
@ -8,9 +8,9 @@ return value : a DValue object containing the deserialized JSON data
|
||||
:see
|
||||
0_DValue
|
||||
json_encode
|
||||
to_bool
|
||||
to_f64
|
||||
to_u64
|
||||
2_DValue_to_bool
|
||||
2_DValue_to_f64
|
||||
2_DValue_to_u64
|
||||
|
||||
:content
|
||||
Deserializes `s` into a `DValue` structure.
|
||||
|
||||
@ -11,7 +11,7 @@ return value : string containing the JSON result
|
||||
>types
|
||||
json_decode
|
||||
0_DValue
|
||||
String
|
||||
0_String
|
||||
html_escape
|
||||
|
||||
:content
|
||||
|
||||
@ -5,7 +5,7 @@ list_every
|
||||
bool list_every(StringList items, function<bool (String)> f)
|
||||
|
||||
:see
|
||||
StringList
|
||||
0_StringList
|
||||
0_DValue
|
||||
filter
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ Use filter(StringList items, function<bool (String)> f)
|
||||
|
||||
:see
|
||||
filter
|
||||
StringList
|
||||
0_StringList
|
||||
|
||||
:content
|
||||
`list_filter()` was removed because `StringList` is `std::vector<String>` and the generic `filter()` helper covers the same behavior without a second implementation to maintain.
|
||||
|
||||
@ -5,7 +5,7 @@ list_find
|
||||
String list_find(StringList items, function<bool (String)> f, String fallback = "")
|
||||
|
||||
:see
|
||||
StringList
|
||||
0_StringList
|
||||
0_DValue
|
||||
filter
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ Use map(StringList items, function<String (String)> f)
|
||||
:see
|
||||
map
|
||||
filter
|
||||
StringList
|
||||
0_StringList
|
||||
|
||||
:content
|
||||
`list_map()` was removed because `StringList` is `std::vector<String>` and the generic `map()` helper covers the same behavior without a second implementation to maintain.
|
||||
|
||||
@ -5,7 +5,7 @@ list_some
|
||||
bool list_some(StringList items, function<bool (String)> f)
|
||||
|
||||
:see
|
||||
StringList
|
||||
0_StringList
|
||||
0_DValue
|
||||
filter
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ list_sort
|
||||
StringList list_sort(StringList items)
|
||||
|
||||
:see
|
||||
StringList
|
||||
0_StringList
|
||||
0_DValue
|
||||
filter
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ list_unique
|
||||
StringList list_unique(StringList items)
|
||||
|
||||
:see
|
||||
StringList
|
||||
0_StringList
|
||||
0_DValue
|
||||
filter
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@ return value : a new list containing the transformed values
|
||||
:see
|
||||
>string
|
||||
filter
|
||||
StringList
|
||||
0_StringList
|
||||
0_DValue
|
||||
|
||||
:content
|
||||
|
||||
@ -12,7 +12,7 @@ markdown_to_ast
|
||||
component
|
||||
component_render
|
||||
json_decode
|
||||
String
|
||||
0_String
|
||||
|
||||
:content
|
||||
Renders Markdown source into HTML and returns the generated markup as a `String`.
|
||||
|
||||
@ -6,7 +6,7 @@ url : target URL for the redirect
|
||||
code : optional HTTP redirect status, defaults to `302`
|
||||
|
||||
:see
|
||||
set_status
|
||||
2_Request_set_status
|
||||
0_Request
|
||||
|
||||
:content
|
||||
|
||||
@ -14,7 +14,7 @@ regex_search
|
||||
regex_search_all
|
||||
regex_replace
|
||||
regex_split
|
||||
String
|
||||
0_String
|
||||
|
||||
:content
|
||||
Tests whether `subject` matches `pattern` from start to end.
|
||||
|
||||
@ -16,7 +16,7 @@ regex_search_all
|
||||
regex_replace
|
||||
split
|
||||
join
|
||||
StringList
|
||||
0_StringList
|
||||
|
||||
:content
|
||||
Splits `subject` wherever `pattern` matches.
|
||||
|
||||
@ -1,20 +0,0 @@
|
||||
:sig
|
||||
void context.set_status(s32 code, String reason = "")
|
||||
|
||||
:params
|
||||
code : HTTP status code
|
||||
reason : optional reason phrase override
|
||||
|
||||
:see
|
||||
0_Request
|
||||
>types
|
||||
|
||||
:content
|
||||
Sets the current request status line and mirrors the numeric status into `context.flags.status`.
|
||||
|
||||
When `reason` is omitted, UCE fills in a standard reason phrase for common HTTP status codes such as `200`, `302`, `400`, `404`, and `500`.
|
||||
|
||||
Related:
|
||||
|
||||
- PHP: `http_response_code()` and explicit status-line header control
|
||||
- JavaScript / Node.js: `res.status(...)`, `Response` init status, or low-level status assignment on an HTTP response
|
||||
@ -1,37 +1,22 @@
|
||||
:sig
|
||||
bool DValue::to_bool(bool default_value = false) const
|
||||
bool to_bool(String s, bool fallback = false)
|
||||
|
||||
:params
|
||||
default_value : returned when the value is missing or empty
|
||||
return value : the value as a boolean, or `default_value`
|
||||
s : string to parse
|
||||
fallback : value returned when `s` is empty or not a recognized boolean token
|
||||
return value : parsed bool, or `fallback`.
|
||||
|
||||
:see
|
||||
>types
|
||||
0_DValue
|
||||
json_decode
|
||||
to_f64
|
||||
to_u64
|
||||
to_string
|
||||
to_s64
|
||||
to_f64
|
||||
|
||||
:content
|
||||
Reads a `DValue` value as a boolean. This is a read accessor: it is `const`, never creates or modifies nodes, and dereferences internal references automatically.
|
||||
Parses a trimmed, case-insensitive boolean string.
|
||||
|
||||
String values such as `true`, `yes`, `on`, and `1` read as true. Values such as `false`, `no`, `off`, `0`, and `null` read as false. Numeric values read as true when non-zero.
|
||||
Truthy tokens are `"1"`, `"true"`, `"yes"`, and `"on"`. Falsey tokens are `"0"`, `"false"`, `"no"`, and `"off"`. Empty or unrecognized strings return the fallback.
|
||||
|
||||
`default_value` is returned when the node is unset, holds an empty string, or is an unresolvable reference. Note the truthiness rule: a non-empty string that parses as neither a boolean word nor a number still reads as `true` — only missing/empty values fall back to the default.
|
||||
|
||||
A map-shaped node with exactly one entry unwraps to that entry's value; other maps read as true when non-empty.
|
||||
|
||||
## Example
|
||||
|
||||
```cpp
|
||||
bool log_requests = context.cfg.get_by_path("app/log_requests").to_bool(true);
|
||||
bool wants_compact = context.props["compact"].to_bool();
|
||||
```uce
|
||||
bool enabled = to_bool(context.server->config["FEATURE_ENABLED"], true);
|
||||
```
|
||||
|
||||
Use this when consuming request data, JSON-decoded values, config trees, or component props where the original input may be string-shaped.
|
||||
|
||||
## Related Concepts
|
||||
|
||||
- PHP: `filter_var($v, FILTER_VALIDATE_BOOLEAN)`
|
||||
- JavaScript: `Boolean(value)` plus string handling
|
||||
|
||||
@ -1,42 +1,23 @@
|
||||
:sig
|
||||
f64 DValue::to_f64(f64 default_value = 0) const
|
||||
f64 to_f64(String s, f64 fallback = 0)
|
||||
|
||||
:params
|
||||
default_value : returned when the value is missing or cannot be parsed as a number
|
||||
return value : the value as a floating-point number, or `default_value`
|
||||
s : string to parse
|
||||
fallback : value returned when `s` is empty or not a complete floating-point number
|
||||
return value : parsed f64, or `fallback`.
|
||||
|
||||
:see
|
||||
>types
|
||||
0_DValue
|
||||
json_decode
|
||||
float_val
|
||||
to_bool
|
||||
to_s64
|
||||
to_u64
|
||||
to_s64
|
||||
to_bool
|
||||
float_val
|
||||
|
||||
:content
|
||||
Reads a `DValue` value as a floating-point number. This is a read accessor: it is `const`, never creates or modifies nodes, and dereferences internal references automatically.
|
||||
Parses a trimmed string as a floating-point number.
|
||||
|
||||
String values are trimmed and parsed permissively: numeric forms and the boolean words understood by `to_bool()` both convert. Boolean values become `1.0` or `0.0`.
|
||||
Unlike `float_val()`, the whole trimmed string must be consumed by the parser. Empty strings and partially parsed values such as `"3.5ms"` return the fallback.
|
||||
|
||||
`default_value` is returned when:
|
||||
|
||||
- the node is unset or holds an empty string
|
||||
- the string does not parse as a finite number
|
||||
- the node is map-shaped with more than one entry, or an unresolvable reference
|
||||
|
||||
A map-shaped node with exactly one entry unwraps to that entry's value before converting.
|
||||
|
||||
## Example
|
||||
|
||||
```cpp
|
||||
f64 ratio = context.props["ratio"].to_f64(1.0);
|
||||
f64 threshold = context.cfg.get_by_path("alerts/threshold").to_f64(0.75);
|
||||
```uce
|
||||
f64 timeout = to_f64(context.server->config["REQUEST_TIMEOUT"], 15.0);
|
||||
```
|
||||
|
||||
Use this for numeric config values, JSON-decoded fields, component props, and request data that should be treated as a number.
|
||||
|
||||
## Related Concepts
|
||||
|
||||
- PHP: `floatval()` with a fallback
|
||||
- JavaScript: `parseFloat(x) || fallback`
|
||||
|
||||
@ -1,34 +0,0 @@
|
||||
:sig
|
||||
String DValue::to_json(char quote_char = '"') const
|
||||
|
||||
:params
|
||||
quote_char : quote character used around string output
|
||||
return value : the scalar as a single JSON token
|
||||
|
||||
:see
|
||||
>types
|
||||
0_DValue
|
||||
json_encode
|
||||
json_decode
|
||||
to_string
|
||||
|
||||
:content
|
||||
Renders a single scalar `DValue` value as a JSON token. This is a read accessor: it is `const`, never creates or modifies nodes, and dereferences internal references automatically.
|
||||
|
||||
Strings are escaped and quoted, numbers render as numeric literals, and booleans render as `true` / `false`.
|
||||
|
||||
This is **not** a serializer for nested data: map-shaped nodes render as the placeholder string `"(array)"`. Use `json_encode()` to serialize a whole tree.
|
||||
|
||||
## Example
|
||||
|
||||
```cpp
|
||||
String token = context.props["label"].to_json(); // "\"Don't panic\""
|
||||
String body = json_encode(context.props); // full tree serialization
|
||||
```
|
||||
|
||||
The `quote_char` parameter exists for embedding output inside single-quoted contexts; for HTML attributes prefer double quotes plus `html_escape()`.
|
||||
|
||||
## Related Concepts
|
||||
|
||||
- JavaScript: `JSON.stringify(value)` for a single scalar
|
||||
- PHP: `json_encode($scalar)`
|
||||
@ -1,41 +1,23 @@
|
||||
:sig
|
||||
s64 DValue::to_s64(s64 default_value = 0) const
|
||||
s64 to_s64(String s, s64 fallback = 0)
|
||||
|
||||
:params
|
||||
default_value : returned when the value is missing or cannot be parsed as a number
|
||||
return value : the value as a signed 64-bit integer, or `default_value`
|
||||
s : string to parse
|
||||
fallback : value returned when `s` is empty or not a complete signed integer
|
||||
return value : parsed s64, or `fallback`.
|
||||
|
||||
:see
|
||||
>types
|
||||
0_DValue
|
||||
to_u64
|
||||
to_f64
|
||||
to_bool
|
||||
to_string
|
||||
int_val
|
||||
|
||||
:content
|
||||
Reads a `DValue` value as a signed integer. This is a read accessor: it is `const`, never creates or modifies nodes, and dereferences internal references automatically.
|
||||
Parses a trimmed string as a base-10 signed integer.
|
||||
|
||||
String values are trimmed and parsed permissively: plain integers, floating-point forms (truncated toward zero), and the boolean words understood by `to_bool()` (`yes` reads as `1`) all convert. Results outside the `s64` range clamp to the range boundaries. Boolean values become `1` or `0`.
|
||||
The whole trimmed string must be consumed by the parser. Empty strings and partially parsed values such as `"-12px"` return the fallback.
|
||||
|
||||
`default_value` is returned when:
|
||||
|
||||
- the node is unset or holds an empty string
|
||||
- the string does not parse as a number (`"not-a-number"`)
|
||||
- the node is map-shaped with more than one entry, or an unresolvable reference
|
||||
|
||||
A map-shaped node with exactly one entry unwraps to that entry's value before converting — this matches how single-value rows from query results read.
|
||||
|
||||
## Example
|
||||
|
||||
```cpp
|
||||
s64 page = context.get["page"].to_s64(1);
|
||||
s64 limit = context.cfg.get_by_path("app/page_size").to_s64(25);
|
||||
```uce
|
||||
s64 offset = to_s64(context.params["offset"], 0);
|
||||
```
|
||||
|
||||
`json_decode()` stores JSON numbers as string-valued nodes, so this is the normal way to consume decoded numeric fields.
|
||||
|
||||
## Related Concepts
|
||||
|
||||
- PHP: `intval()` with a fallback
|
||||
- JavaScript: `parseInt(x) || fallback`
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user