feat: build out main
This commit is contained in:
1 parent
1459f7fe37
commit
862de87af6
1 file changed
+182
+182
@@ -374,6 +374,188 @@ const usage =
|
||||
\\ matches a row where the field was never set OR set to an explicit
|
||||
\\ none, e.g. city is_null and age gte i:18 (never uses an index, a
|
||||
\\ sparse row's absence is not something a B-tree entry can represent)
|
||||
\\ (empty expr selects every row; --limit/--offset page the result,
|
||||
\\ limit 0 or omitted means unlimited; --order-by sorts by one or more
|
||||
\\ comma-separated fields, applied left to right (later fields only
|
||||
\\ break ties left by earlier ones), ascending by default or ":desc"
|
||||
\\ per field for descending - rows missing a sort field sort first
|
||||
\\ on it)
|
||||
\\ table explain <table> [expr...]
|
||||
\\ reports which strategy `table select` would use for the same
|
||||
\\ <table>/expr WITHOUT running the query: full scan, a single-field
|
||||
\\ index (equality or range), or a composite index (equality or range,
|
||||
\\ naming how many of its leading columns the expr actually pinned down)
|
||||
\\ table update <table> --set field=value[,field=value...] [expr...]
|
||||
\\ applies the --set field list to every row matched by expr (empty expr
|
||||
\\ updates every row); each set field overrides an existing field of the
|
||||
\\ same name or is added if the row does not have it; unmentioned fields
|
||||
\\ are left as-is; secondary/composite indexes on a changed field are
|
||||
\\ kept in sync exactly like `table put` would; prints the number of
|
||||
\\ rows updated
|
||||
\\ table delete <table> [expr...]
|
||||
\\ removes every row matched by expr (empty expr deletes every row, same
|
||||
\\ convention as `table select`/`table update`); secondary/composite
|
||||
\\ indexes on the deleted rows are kept in sync exactly like `table del`
|
||||
\\ would for a single row; prints the number of rows deleted
|
||||
\\ table index create|drop <table> <field...> (multiple fields = composite index)
|
||||
\\ create --unique <table> <field>: single-field index that also enforces the
|
||||
\\ field holds a distinct value across every row (SQL UNIQUE); refuses to
|
||||
\\ install over data that already has a duplicate; dropping the index drops
|
||||
\\ the constraint too. Not available for composite (multi-field) indexes.
|
||||
\\ table fk create <table> <field> <refTable> <refField> [restrict|cascade]
|
||||
\\ installs a FOREIGN KEY: every <table> row's (non-null) <field> value must
|
||||
\\ name an existing <refField> on <refTable> (SQL FOREIGN KEY REFERENCES);
|
||||
\\ <refField> must be either the special primary-key name "__pk" or a field
|
||||
\\ already carrying its own --unique index on <refTable>, or the create is
|
||||
\\ refused; refuses to install over a <table> row whose current value has
|
||||
\\ no matching target; rows missing <field> entirely are exempt (nullable FK).
|
||||
\\ Last argument picks ON DELETE behavior for a `table delete`/`table_delete`
|
||||
\\ against <refTable>, default "restrict": restrict refuses the delete while
|
||||
\\ a <table> row still points at it, cascade removes those rows too (and
|
||||
\\ anything cascading from them, recursively). A `txn <script>` delete
|
||||
\\ always restricts regardless of this setting - cascade only fires through
|
||||
\\ the plain (non-transactional) delete path
|
||||
\\ table fk drop <table> <field>
|
||||
\\ removes the foreign key constraint on <field>, if any
|
||||
\\ table check create <table> <name> <expr...>
|
||||
\\ installs a named CHECK constraint (SQL CHECK): every row put into <table>
|
||||
\\ from now on must evaluate <expr> (same predicate language as `table select`)
|
||||
\\ to true, or the put is refused with CheckViolation; refuses to install over
|
||||
\\ existing rows that already fail <expr>; a malformed <expr> is refused with
|
||||
\\ InvalidCheckExpression before anything is persisted
|
||||
\\ table check drop <table> <name>
|
||||
\\ removes the named CHECK constraint, if any
|
||||
\\ table join [--left|--right|--full] <leftTable> <leftField> <rightTable> <rightField>
|
||||
\\ inner equi-join by default: prints "L <row>" / "R <row>" for every matched pair;
|
||||
\\ --left makes it a left outer join: every left row still prints once, with
|
||||
\\ "R (nil)" when it has no match on the right instead of being dropped;
|
||||
\\ --right is the mirror image: every right row prints once, "L (nil)" when unmatched;
|
||||
\\ --full is the union of both: every row on either side prints at least once;
|
||||
\\ uses an index on <rightField> (or <leftField> for --right) when one exists,
|
||||
\\ hash-joins otherwise; [--limit N] [--offset N] window the already-joined
|
||||
\\ result, same convention as `table select` (limit 0 or omitted = unlimited)
|
||||
\\ values/keys are typed: i:<int> f:<float> b:true|false s:<text>, bare text defaults to s:
|
||||
\\ table aggregate <table> <groupField|*> <spec>[,<spec>...] [expr...] [having <expr>]
|
||||
\\ [order <field[:desc]>[,field...]] [--limit N] [--offset N]
|
||||
\\ spec is count | count:<field> | sum:<field> | avg:<field> | min:<field> | max:<field> |
|
||||
\\ distinct:<field> (COUNT DISTINCT), comma-separated for more than one in the same
|
||||
\\ pass; groupField "*" means no
|
||||
\\ grouping (a single result row over every row matching expr, same predicate
|
||||
\\ grammar as `table select`, and having/order/--limit/--offset are all ignored);
|
||||
\\ rows missing groupField are excluded from every group, rows missing a spec's
|
||||
\\ field are excluded from just that spec; --limit/--offset window the result
|
||||
\\ groups, same convention as `table select`;
|
||||
\\ an optional literal `having <expr>` after the row-filtering expr filters the
|
||||
\\ RESULT groups after aggregation (same expr grammar, evaluated before
|
||||
\\ order/--limit/--offset); its fields are the printed result labels (bare kind
|
||||
\\ name for count, else "<kind>_<field>" e.g. sum_score) plus groupField itself,
|
||||
\\ so e.g. `table aggregate orders city sum:total having sum_total gt i:1000`;
|
||||
\\ an optional literal `order <field[:desc]>[,field...]` after having (or right
|
||||
\\ after the row-filtering expr if there is no having) sorts the result groups
|
||||
\\ before --limit/--offset windows them, one or more comma-separated columns
|
||||
\\ applied left to right same as `table select`'s --order-by, each field naming
|
||||
\\ either groupField or a result label (same two names having's expr can use),
|
||||
\\ e.g. `table aggregate orders city sum:total order sum_total:desc --limit 3`
|
||||
\\ (top 3 cities by total, without needing having at all); without groupField
|
||||
\\ among the sort fields, ties on every named field keep first-seen order
|
||||
\\ (stable sort)
|
||||
\\ table window <table> <kind[:field]>[,<kind[:field]>...] [expr...] [partition <field>[,field...]]
|
||||
\\ [order <field[:desc]>[,field...]] [--limit N] [--offset N] [--range]
|
||||
\\ annotates every matching row with one or more computed window-function
|
||||
\\ columns instead of collapsing rows like `table aggregate` does; kind is
|
||||
\\ row_number | rank | dense_rank (no :field) | sum:<field> | avg:<field> |
|
||||
\\ count | count:<field> | count_distinct:<field> | min:<field> | max:<field> |
|
||||
\\ first_value:<field> | last_value:<field> | nth_value:<field>:<n>[:<default>] |
|
||||
\\ lag:<field>[:<offset>[:<default>]] | lead:<field>[:<offset>[:<default>]];
|
||||
\\ a comma-separated list (e.g. `sum:total,avg:total,rank`) computes every
|
||||
\\ column over the SAME partition/order/frame, printed in the same order
|
||||
\\ after the row's own fields;
|
||||
\\ an optional literal `partition <field>[,field...]` splits rows into
|
||||
\\ independent groups (like GROUP BY, first-seen order; omitted = one
|
||||
\\ partition covering every matching row) and an optional literal `order
|
||||
\\ <field[:desc]>[,field...]` (same syntax as `table select`'s
|
||||
\\ --order-by) decides the ranking/running-total walk within each
|
||||
\\ partition - partition must come before order if both are given;
|
||||
\\ without order, rank/dense_rank treat the whole partition as tied
|
||||
\\ (every row gets 1) and sum/avg/count/count_distinct/min/max give every
|
||||
\\ row the same whole-partition total; with order, sum/avg/count/
|
||||
\\ count_distinct/min/max become a running total walked in that order
|
||||
\\ instead, by default one physical
|
||||
\\ ROW at a time - even a row tied with its predecessor on `order` gets
|
||||
\\ its OWN individual running value; --range switches this to SQL's
|
||||
\\ actual default RANGE frame instead, where rows tied on every `order`
|
||||
\\ column share the LAST tied row's combined value rather than their own
|
||||
\\ (e.g. two rows both on day 1 both show day 1's combined total, not a
|
||||
\\ half/full split); --range has no effect without `order` (both frames
|
||||
\\ already agree there) and is rejected outright together with
|
||||
\\ row_number/rank/dense_rank (neither takes a frame clause in standard
|
||||
\\ SQL either); --limit/--offset window the printed rows in the SAME
|
||||
\\ partition-then-order walk the window computation itself uses (every
|
||||
\\ partition's rows in `order`, first-seen partition order), not raw
|
||||
\\ scan order - e.g. `table window orders row_number partition city
|
||||
\\ order amount:desc --limit 3` prints (up to) the first 3 rows of the
|
||||
\\ first-seen partition in that order, not an arbitrary scan-order slice;
|
||||
\\ lag/lead read <field>'s value <offset> rows before/after the current
|
||||
\\ row within the partition's `order` sequence (first-seen order if no
|
||||
\\ `order` given), always as a DISTINCT physical position even when tied
|
||||
\\ with a neighbor on `order` (unlike the RANGE running-aggregate frame,
|
||||
\\ which collapses ties); a row whose target falls outside the partition
|
||||
\\ gets <default> (an `i:`/`f:`/`b:`/`s:`-prefixed literal, same grammar
|
||||
\\ as put's field=value) or SQL NULL if omitted; <offset> defaults to 1
|
||||
\\ if omitted; --range is rejected outright with lag/lead, same as with
|
||||
\\ row_number/rank/dense_rank (a frame clause has no meaning for either);
|
||||
\\ first_value/last_value/nth_value read <field>'s value from the current
|
||||
\\ frame's first/last/n-th row - UNLIKE lag/lead, these DO respect --range:
|
||||
\\ first_value is always the partition's first row (same in both frames),
|
||||
\\ but last_value's frame end follows the running-aggregate split - without
|
||||
\\ --range (ROWS, ending at CURRENT ROW) last_value degenerates to the
|
||||
\\ row's own field (SQL's well-known gotcha), with --range it is instead
|
||||
\\ the LAST row of the current tie group on `order`; without `order` at
|
||||
\\ all, both give every row the whole partition's first/last value;
|
||||
\\ nth_value shares first_value/last_value's frame exactly (same start,
|
||||
\\ same ROWS/RANGE/no-order end) but reads the <n>-th row (1-based,
|
||||
\\ required - unlike lag/lead's <offset>, SQL's NTH_VALUE has no default
|
||||
\\ position) counted from the frame's START; a row whose current frame is
|
||||
\\ still smaller than <n> gets <default> (same grammar as lag/lead's, SQL
|
||||
\\ NULL if omitted) - e.g. under ROWS, nth_value:total:2 is NULL on the
|
||||
\\ first row of every partition (frame size 1) and 2nd-row's value from
|
||||
\\ then on, once the frame has grown enough to contain it
|
||||
\\ table export <table> csv|json <path>
|
||||
\\ writes every row to <path>; the column/key set is the union of every
|
||||
\\ field name across every row (primary key first, "__pk", then
|
||||
\\ first-seen order), a row missing a column just omits that cell/key
|
||||
\\ rather than writing empty/null; every value is written as a typed
|
||||
\\ string (i:/f:/b:/s:/x:/n:, same prefixes as put's field=value, plus
|
||||
\\ x: for raw bytes hex and n: for none) so re-importing reproduces the
|
||||
\\ exact original type, including floats (encoded as exact bits, not a
|
||||
\\ decimal that could round-trip lossy); prints the row count written
|
||||
\\ table import <table> csv|json <path>
|
||||
\\ reads rows written by `table export` (or any file in the same shape)
|
||||
\\ back into <table> via `table put`, so existing rows sharing a
|
||||
\\ primary key are overwritten and secondary/composite indexes stay in
|
||||
\\ sync; the "__pk" column/key is required; prints the row count read
|
||||
\\
|
||||
\\ txn <script-file> apply a script of `put|del <table> <pk> [field=value ...]`
|
||||
\\ lines as one atomic transaction (all-or-nothing, error.Conflict
|
||||
\\ aborts with nothing applied); blank lines and #comments skipped
|
||||
\\
|
||||
\\ repl [--script <file>] interactive shell over this database: put/get/del/
|
||||
\\ scan/stats/flush/compact plus table put/get/del and
|
||||
\\ coll <kind> <op> [args...] (counter/hash/set/list/
|
||||
\\ zset), with begin/commit/rollback bracketing an
|
||||
\\ interactive transaction (get mid-transaction can
|
||||
\\ steer the next put, unlike a static `txn` script).
|
||||
\\ Reads stdin with a prompt by default, or a file
|
||||
\\ non-interactively with --script.
|
||||
\\
|
||||
\\ replicate <replica-dir> [--once] [--interval-ms <n>]
|
||||
\\ tail this database's WAL and apply new writes onto
|
||||
\\ <replica-dir> (opened/created fresh). Runs a bootstrap
|
||||
\\ fullResync first, then loops calling syncOnce every
|
||||
\\ interval-ms (default 200) until interrupted, or once
|
||||
\\ and exit if --once is given. Recovers automatically
|
||||
\\ from a fallen-behind tailer (primary flushed before
|
||||
\\ catching up) via another fullResync.
|
||||
\\
|
||||
;
|
||||
|
||||
|
||||
Reference in new issue
Block a user