feat: extend main

This commit is contained in:
dualfroz committed 2026-09-06 18:49:13 +02:00
1 parent 0491437ef8
commit 668a5c093d
1 file changed
+188 -3
+188 -3
View File
@@ -1,21 +1,206 @@
const std = @import("std");
const cobalt = @import("root.zig");
const Value = cobalt.row.Value;
const Field = cobalt.row.Field;
const usage =
\\cobalt - LSM key/value store
\\
\\usage: cobalt <dir> <command> [args]
\\
\\commands:
\\ put <key> <value> store a value
\\ get <key> print a value or (nil)
\\ put <key> <value> [--ttl <seconds>]
\\ store a value, optionally set to expire
\\ get <key> print a value or (nil); a key past its ttl
\\ reads as (nil) and is deleted lazily on this read
\\ del <key> delete a key
\\ expire <key> <seconds> set/replace a key's ttl; error if the key does
\\ not currently exist (nonexistent keys have no ttl to set)
\\ persist <key> remove a key's ttl, making it immortal again
\\ ttl <key> print seconds left, -1 if no ttl, -2 if no such key
\\ expire-sweep actively delete every key whose ttl is due,
\\ not just the next one someone happens to read;
\\ prints how many were reaped
\\ scan [start] [end] forward range scan, start inclusive, end exclusive
\\ rscan [start] [end] reverse range scan
\\ prefix <prefix> scan every key under a prefix
\\ compact run full leveled compaction
\\ stats print database statistics
\\ stats [--prom] print database statistics (optionally as Prometheus text)
\\ verify <n> write n keys, reopen, check durability and scan order
\\ serve [host:port] [--rate-limit <capacity> <per-second>]
\\ [--per-conn-rate-limit <capacity> <per-second>] [--auth]
\\ [--session-ttl <seconds>] [--session-sweep-interval <seconds>]
\\ [--ttl-sweep-interval <seconds>] [--coll-ttl-sweep-interval <seconds>]
\\ run a TCP server (default 127.0.0.1:6380),
\\ optionally capping requests with a shared
\\ token bucket and/or a private one per
\\ connection (both may be given together);
\\ --auth requires an AUTH before any op but
\\ ping, refuses to start if no admin user
\\ exists yet (see `user add`); --session-ttl
\\ (requires --auth) makes AUTH return a
\\ token valid for that many seconds - a new
\\ connection can present it via AUTH_TOKEN
\\ instead of the password, and the role it
\\ grants stops working once the ttl elapses
\\ even on a connection that never disconnects;
\\ --session-sweep-interval (requires
\\ --session-ttl) periodically drops sessions
\\ that expired but nobody ever presented again;
\\ --ttl-sweep-interval periodically reaps every
\\ key whose ttl is due, independent of --auth
\\ (like local `expire-sweep`, but automatic);
\\ --coll-ttl-sweep-interval does the same for
\\ whole collections (like local
\\ `coll expire-sweep`), independent of
\\ --ttl-sweep-interval - either, both, or
\\ neither may be given
\\
\\cobalt <host:port> remote-select <table> [expr...] [--limit N] [--offset N]
\\ [--order-by field[:desc][,field[:desc]...]]
\\ [--user NAME --pass PASS] [--token TOKEN]
\\ connect to a running `cobalt serve` and run a
\\ `table select` there (same expr grammar as
\\ local `table select`; empty expr selects
\\ every row) - no local Db is opened;
\\ --user/--pass authenticate first, needed
\\ only if the server was started with --auth;
\\ --token authenticates with a previously
\\ issued session token instead of a password
\\ (requires the server to have --session-ttl)
\\
\\cobalt <host:port> remote-explain <table> [expr...]
\\ [--user NAME --pass PASS] [--token TOKEN]
\\ connect to a running `cobalt serve` and run a
\\ `table explain` there (same expr grammar as
\\ local `table select`) - no local Db is opened;
\\ --user/--pass or --token authenticate first,
\\ same as `remote-select`
\\
\\cobalt <host:port> remote-update <table> --set field=value[,field=value...] [expr...]
\\ [--user NAME --pass PASS] [--token TOKEN]
\\ connect to a running `cobalt serve` and run a
\\ `table update` there (same --set grammar and
\\ expr grammar as local `table update`; empty
\\ expr updates every row) - no local Db is
\\ opened; prints the number of rows updated;
\\ --user/--pass or --token authenticate first,
\\ same as `remote-select`
\\
\\cobalt <host:port> remote-delete <table> [expr...]
\\ [--user NAME --pass PASS] [--token TOKEN]
\\ connect to a running `cobalt serve` and run a
\\ `table delete` there (same expr grammar as
\\ local `table delete`; empty expr deletes
\\ every row) - no local Db is opened; prints
\\ the number of rows deleted; --user/--pass or
\\ --token authenticate first, same as
\\ `remote-select`
\\
\\cobalt <host:port> remote-export <table> csv|json <path>
\\ [--user NAME --pass PASS] [--token TOKEN]
\\ connect to a running `cobalt serve` and run a
\\ `table export` there (same output shape as
\\ local `table export`), writing the result to
\\ <path> on THIS machine - no local Db is
\\ opened; prints the row count written;
\\ --user/--pass or --token authenticate first,
\\ same as `remote-select`
\\
\\cobalt <host:port> remote-import <table> csv|json <path>
\\ [--user NAME --pass PASS] [--token TOKEN]
\\ connect to a running `cobalt serve` and run a
\\ `table import` there, reading <path> on THIS
\\ machine and sending its bytes in one frame -
\\ no local Db is opened; prints the row count
\\ imported; --user/--pass or --token
\\ authenticate first, same as `remote-select`
\\
\\cobalt <host:port> remote-join [--left|--right|--full] <leftTable> <leftField>
\\ <rightTable> <rightField> [--left-expr E] [--right-expr E]
\\ [--limit N] [--offset N]
\\ [--user NAME --pass PASS] [--token TOKEN]
\\ connect to a running `cobalt serve` and run a
\\ `table join` there (same 4 modes as local
\\ `table join`; --left-expr/--right-expr are
\\ the same expr grammar as `table select`,
\\ filtering each side before the join runs;
\\ --limit/--offset window the already-joined
\\ result, same convention as `table select`) -
\\ no local Db is opened; --user/--pass or
\\ --token authenticate first, same as
\\ `remote-select`
\\
\\cobalt <host:port> remote-aggregate <table> <groupField|*> <spec>[,<spec>...] [expr...]
\\ [having <expr>] [order <field[:desc]>[,field...]]
\\ [--limit N] [--offset N]
\\ [--user NAME --pass PASS] [--token TOKEN]
\\ connect to a running `cobalt serve` and run a
\\ `table aggregate` there (same spec grammar
\\ as local `table aggregate`: count |
\\ count:field | sum:field | avg:field |
\\ min:field | max:field | distinct:field,
\\ comma-separated;
\\ `*` as groupField means no GROUP BY, always
\\ at most one result row and --limit/--offset
\\ are ignored; expr filters rows before
\\ aggregating, same grammar as `table
\\ select`; an optional `having <expr>` after
\\ expr filters the result groups after
\\ aggregation, same as local `table
\\ aggregate`; an optional `order
\\ <field[:desc]>[,field...]` after having
\\ sorts the result groups server-side before
\\ --limit/--offset window them, same as
\\ local `table aggregate`; --limit/--offset
\\ window the result groups, same convention
\\ as `table select`) - no local Db is opened;
\\ --user/--pass or --token authenticate
\\ first, same as `remote-select`
\\
\\cobalt <host:port> remote-window <table> <kind[:field]>[,<kind[:field]>...] [expr...]
\\ [partition <field>[,field...]]
\\ [order <field[:desc]>[,field...]]
\\ [--limit N] [--offset N] [--range]
\\ [--user NAME --pass PASS] [--token TOKEN]
\\ connect to a running `cobalt serve` and run a
\\ `table window` there (same spec-list
\\ grammar as local `table window`: row_number |
\\ rank | dense_rank | count | count:field |
\\ count_distinct:field | sum:field | avg:field |
\\ min:field | max:field | first_value:field |
\\ last_value:field | nth_value:field:n[:default] |
\\ lag:field[:offset[:default]] |
\\ lead:field[:offset[:default]],
\\ comma-separated for multiple
\\ annotation columns sharing one partition/
\\ order/frame; lag/lead read the field's value
\\ `offset` rows before/after the current row
\\ within the partition's order sequence
\\ (default offset 1, default value SQL NULL
\\ unless an `i:`/`f:`/`b:`/`s:`-prefixed
\\ `default` literal is given); first_value/
\\ last_value/nth_value read the current
\\ frame's first/last/n-th row (n is 1-based,
\\ required, no SQL default) - UNLIKE lag/lead,
\\ these respect --range - see local `table
\\ window`'s help for the full frame-end
\\ semantics; expr
\\ filters rows before annotation, same
\\ grammar as `table select`;
\\ an optional `partition <field>[,field...]`
\\ after expr splits rows into independent
\\ groups, same as local `table window`; an
\\ optional `order <field[:desc]>[,field...]`
\\ after partition orders rows within each
\\ partition for ranking/running-aggregate
\\ purposes; every matching row comes back
\\ annotated (never collapsed, unlike `table
\\ aggregate`); --limit/--offset window WHICH
\\ rows are returned, walked in the same
\\ partition-then-order sequence used to
\\ compute them, not raw scan order; --range
\\
;