From 668a5c093d6ba50e0c56ceb018106299a8db521f Mon Sep 17 00:00:00 2001 From: DualFroz Date: Sun, 6 Sep 2026 18:49:13 +0200 Subject: [PATCH] feat: extend main --- src/main.zig | 191 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 188 insertions(+), 3 deletions(-) diff --git a/src/main.zig b/src/main.zig index b3d9650..93f22e9 100644 --- a/src/main.zig +++ b/src/main.zig @@ -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 [args] \\ \\commands: - \\ put store a value - \\ get print a value or (nil) + \\ put [--ttl ] + \\ store a value, optionally set to expire + \\ get print a value or (nil); a key past its ttl + \\ reads as (nil) and is deleted lazily on this read \\ del delete a key + \\ expire set/replace a key's ttl; error if the key does + \\ not currently exist (nonexistent keys have no ttl to set) + \\ persist remove a key's ttl, making it immortal again + \\ ttl 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 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 write n keys, reopen, check durability and scan order + \\ serve [host:port] [--rate-limit ] + \\ [--per-conn-rate-limit ] [--auth] + \\ [--session-ttl ] [--session-sweep-interval ] + \\ [--ttl-sweep-interval ] [--coll-ttl-sweep-interval ] + \\ 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 remote-select [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 remote-explain
[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 remote-update
--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 remote-delete
[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 remote-export
csv|json + \\ [--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 + \\ on THIS machine - no local Db is + \\ opened; prints the row count written; + \\ --user/--pass or --token authenticate first, + \\ same as `remote-select` + \\ + \\cobalt remote-import
csv|json + \\ [--user NAME --pass PASS] [--token TOKEN] + \\ connect to a running `cobalt serve` and run a + \\ `table import` there, reading 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 remote-join [--left|--right|--full] + \\ [--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 remote-aggregate
[,...] [expr...] + \\ [having ] [order [,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 ` after + \\ expr filters the result groups after + \\ aggregation, same as local `table + \\ aggregate`; an optional `order + \\ [,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 remote-window
[,...] [expr...] + \\ [partition [,field...]] + \\ [order [,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...]` + \\ after expr splits rows into independent + \\ groups, same as local `table window`; an + \\ optional `order [,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 \\ ;