-
Notifications
You must be signed in to change notification settings - Fork 0
tcl
mvx is the classic shell: a prompt, a builtin table, VOC
dispatch, and nothing else. Verbs are compiled BASIC programs.
mvx -a /path/to/account # log on to an account
mvx -a acct -c "LIST PARTS" # one command (ssh/cron style)Interactive sessions have arrow-key history (persisted in
~/.mvx_history) and the prompt names the account.
Resolution order for a typed command: builtins → the account VOC → linked packages (in order) → the system account. Local entries override everything; the system account is the source of truth for standard verbs.
OFF / QUIT / BYE
|
end the session |
LOGTO dir |
switch accounts |
! command |
raw Unix (unrestricted tier) |
SH |
interactive shell (unrestricted tier) |
| verb | |
|---|---|
CREATE-FILE name {DIR|USING driver {conn}} |
create a file — local, directory, or on another backend |
DELETE-FILE name |
delete a file |
CLEAR-FILE name |
delete every record |
LISTF |
the account's files |
COUNT {DICT} file {WITH item op value} |
record count; pushes count(*) (optionally filtered) into a SQL backend, or uses an active select list |
SUM {DICT} file field {WITH item op value} |
total a numeric field; pushes sum(col) into a SQL backend when the field is a mapped NUMERIC column, else scans and OCONVs |
LIST {DESCRIBE} {DICT} file {items} {WITH item op value {AND …}} {BY item} |
query; multiple WITH/AND conditions are ANDed (pushed to one SQL WHERE); DESCRIBE prints the plan instead of running it |
SORT {DESCRIBE} {DICT} file {items} {WITH item op value} {BY item} {FIRST n} |
like LIST, but sorted by id (or the BY key); FIRST n keeps the top n, pushed to ORDER BY … LIMIT on a SQL backend when the BY field is a mapped column |
SELECT {DESCRIBE} {DICT} file {WITH item op value} |
form a select list for the next command |
SSELECT {DESCRIBE} {DICT} file {WITH item op value} {BY item} |
like SELECT, but the list is sorted |
MAP file {items...|ALL} {DATA} |
the relational schema the named items imply (SQL mapping preview) |
CREATE-MAP file field… |
declare the mapping (%MAP%) + build it; writes are then mirrored live |
BUILD-MAP file field… {PROGRESS} |
materialise the mapping in the backend and backfill (SQL columns); PROGRESS shows a live indicator |
LIST-MAPS |
the account's mapped files: mode, state (current/stale vs the dictionary), and fields |
MAP-MODE file {native|mirror} |
show or set the write policy (mirror: NULL on mismatch; native: reject the write) |
DELETE-MAP file |
drop a mapping — tear down its columns/child tables and stop mirroring |
CT {DICT} file id |
show a record, numbered attributes |
COPY file id TO {file2} id2 |
copy a record |
DELETE file id {id...} |
delete records |
ED file id |
the built-in line editor (any tier) |
VI file id |
edit a record in an external editor (unrestricted) |
BASIC file item {NODEBUG} {STRIP} |
compile to an object (developer) |
CATALOG file item {NODEBUG} {STRIP} |
compile, link and publish (developer) |
PORT-SOURCE file item {TO file2} {item2} |
rewrite C-style comments as classic |
CREATE-INDEX file item / DELETE-INDEX / LIST-INDEXES
|
secondary indexes |
LINK-PKG path / UNLINK-PKG path / LIST-PKGS
|
packages |
WHO TIME DATE
|
session information |
EXPORT {DICT} file {dir} |
copy records (or a dictionary) to a directory file |
BUILD |
provision an account from its git-tracked config (post-clone) |
IMPORT file {dir} |
mirror a directory file back (full sync) |
GIT add|commit|branch|checkout|merge|cherry-pick|... |
git for records: full porcelain incl. branching |
SET-CREDENTIAL driver target key field=value ... |
store a backend secret in .mvx-private (git-ignored) |
LIST-CREDENTIALS |
list stored credentials, values masked |
SET-CONNECTION name field=value ... |
define a named connection profile (@name in BINDINGS) |
LIST-CONNECTIONS |
list connection profiles, secret fields masked |
SELECT leaves its list for the next command:
> SELECT PARTS WITH COLOR = blue
2 record(s) selected
> LIST PARTS NAME PRICE only the selected records
The list is consumed exactly once. Inside a program, EXECUTE "SELECT ..." followed by READNEXT uses the same mechanism.
Add DESCRIBE (or EXPLAIN) to LIST, SORT, SELECT, or SSELECT
and the verb prints the plan the backend would use without running the
query. The word can go right after the verb (LIST DESCRIBE …) or at
the end of the sentence — either way it does the same thing. On a SQL
backend the plan is the SQL text the push-down would issue, so you can see
exactly what work moves server-side:
> LIST DESCRIBE CUST STATE WITH STATE = "VIC" AND PRICE > "500"
postgres: SELECT id FROM "acct"."CUST" WHERE "STATE" = 'VIC'
AND NULLIF("acct".mvx_attr(rec,3),'')::numeric > '500'::numeric
> SORT ORDERS BY TOTAL FIRST 10 EXPLAIN
postgres: SELECT id FROM "acct"."ORDERS" ORDER BY "TOTAL" LIMIT 10
The plan follows the same push-down rules the query itself would: a
mapped identity column is compared as a column, an unmapped or converted
field through the record blob (mvx_attr), and a numeric range as a
numeric comparison. When a condition can't be pushed (an @ID filter,
a TRANS() join to another backend, a text range) the plan says so and
notes that the verb applies it while scanning:
> LIST CUST WITH @ID = "C1000" DESCRIBE
postgres: SELECT id FROM "acct"."CUST"; 1 condition(s) applied in the verb
The description is backend-specific: a store with no server-side query planner (the local LMDB and directory backends) reports that the driver returns the id list — an index lookup when one exists, otherwise a sequential scan — and the verb applies the conditions and ordering. A future document backend would render its own native query the same way.
The classic line editor: ED FILE ID.
| Enter | next line |
| n | go to line n |
L {n} |
list n lines |
T / B
|
top / bottom |
I |
insert after current line — . alone ends input |
DE {n} |
delete n lines |
R/old/new |
replace in the current line |
FI |
file (save) and exit |
EX |
exit without saving |
Every spawn — !, SH, EXECUTE, and the compiler — passes through
one gate in the runtime, controlled by $MVXPRIV:
| tier | may |
|---|---|
| restricted (default) | run verbs, EXECUTE sentences |
| developer | + compile (BASIC, CATALOG, COMPILE()) |
| unrestricted | + raw Unix (!, SH) |
The check lives in the runtime because anyone who can compile could call the primitives directly — a shell-only check would be decorative.