camus-cli
camus-cli is the interactive command-line SQL shell for CamusDB.
It connects through the CamusDB .NET driver and gives you:
- an interactive SQL prompt
- multiline editing
- syntax highlighting
- Tab autocompletion
- command history
- transaction commands
- SQL script execution
- non-interactive SQL execution with
-e - database switching
- vertical query output for wide rows
- built-in workload helpers
Install
Install the global tool:
dotnet tool install --global CamusDB.SqlSh
Update it:
dotnet tool update --global CamusDB.SqlSh
The executable name installed by the tool is:
camus-cli
The current tool package targets net10.0.
Basic Usage
Start the shell with defaults:
camus-cli
With no connection string, the shell tries the local gRPC listener first and falls back to the local REST listener:
Endpoint=http://localhost:5096;Database=<database>;Protocol=grpc
Endpoint=http://localhost:5095;Database=<database>;Protocol=rest
If you do not pass a positional database name, the connection starts without a selected database. System-level commands still work, and you can create or select a database from the shell:
CREATE DATABASE IF NOT EXISTS test;
USE test;
Open a different database with the positional database argument:
camus-cli northwind
This tries http://localhost:5096 with Protocol=grpc first, then
http://localhost:5095 with Protocol=rest.
Open a custom endpoint and database with an explicit connection string:
camus-cli -c "Endpoint=http://localhost:5095;Database=northwind"
The connection string must include a valid absolute Endpoint. Include
Database when you want the shell to start with a selected database.
If the connection string does not include Protocol=..., the shell tries gRPC
and then REST against the supplied endpoint. If you include Protocol=grpc or
Protocol=rest, that explicit choice is honored with no fallback.
If no database is selected, system-level commands such as CREATE DATABASE,
DROP DATABASE, RENAME DATABASE, ALTER DATABASE ... RENAME TO,
COMMENT ON DATABASE, CREATE USER, ALTER USER, DROP USER, GRANT,
REVOKE, SHOW GRANTS, CREATE DATABASE ... RELINK TO, SHOW DATABASES,
SHOW ORPHAN DATABASES, SHOW BRANCHES FROM ..., and SHOW ANCESTORS FROM ...
still work. Table DDL, DML, table orphan recovery, and ordinary queries require
a selected database.
Authentication
CamusDB authentication is off by default. A shell started without credentials behaves as before. Against a server with authentication enabled, pass a user and password:
camus-cli northwind -u app -p app-secret
If -u is given without -p, the shell prompts for the password without
echoing it:
camus-cli northwind -u app
Credentials can also come from environment variables:
export CAMUS_USER=app
export CAMUS_PASSWORD=app-secret
camus-cli northwind
or from the connection string:
camus-cli -c "Endpoint=https://db.example.com:7141;Database=northwind;User=app;Password=app-secret"
Flags override the same keys inside -c. If another process already obtained a
bearer token, pass it with --token or CAMUS_ACCESS_TOKEN; the token is used
directly and is not renewed.
The driver exchanges the password once for a short-lived bearer token. Later
statements carry the token, not the password, and the driver renews it before
expiry when it has the password. Prefer the prompt or CAMUS_PASSWORD over
-p on shared hosts because process command lines are visible to other local
users.
User and grant administration works before a database is selected because those statements are server-level:
CREATE USER app IDENTIFIED BY 'app-secret';
ALTER USER app IDENTIFIED BY 'rotated-secret';
GRANT SELECT, INSERT ON northwind.* TO app;
GRANT SELECT ON northwind.orders TO reader;
REVOKE INSERT ON northwind.* FROM app;
SHOW GRANTS FOR app;
DROP USER app;
Statements that inline a password with IDENTIFIED ... BY '...' remain
available in in-memory history during the session, but are not written to the
on-disk history file.
Common auth errors:
| Code | Meaning |
|---|---|
CADB0516 | Not authenticated: missing, invalid, expired, or rejected credentials. |
CADB0517 | Authenticated, but missing a privilege on a table touched by the statement, including joins and subqueries. |
CADB0519 | The server requires TLS for credential-bearing requests. Use https://, or configure the server for a trusted TLS-terminating proxy. |
Command Line Syntax
camus-cli [database] [options]
camus-cli workload <init|run> <bank|northwind|factory|tpcc> [options]
Options:
| Option | Description |
|---|---|
[database] | Optional database name. If omitted, the shell starts without a selected database. |
-c, --connection-source | Full connection string. If it has no Database=..., the shell starts without a selected database. |
-e, --execute | Execute one SQL string and exit instead of starting the interactive shell. |
-u, --user | User to authenticate as. |
-p, --password | Password for -u. If omitted in interactive use, the shell prompts. |
--token | Use an existing bearer token instead of logging in with a password. |
--force-rich | Force the rich editor on terminals whose capabilities are not detected automatically. |
--diagnose-terminal | Print terminal capability detection details and exit. |
-h, --help | Show help. |
-v, --version | Show version. |
Environment variables:
| Variable | Description |
|---|---|
CAMUS_FORCE_RICH | Set to 1, true, or yes to force the rich editor. |
CAMUS_USER | Default for -u. |
CAMUS_PASSWORD | Default for -p. Useful in scripts because it keeps the password out of the process command line. |
CAMUS_ACCESS_TOKEN | Default for --token. |
Examples:
camus-cli
camus-cli mydb
camus-cli mydb -u app
camus-cli mydb -u app -p app-secret
camus-cli -c "Endpoint=http://localhost:5095;Database=mydb"
camus-cli -c "Endpoint=http://localhost:5096;Database=mydb;Protocol=grpc"
camus-cli -c "Endpoint=http://localhost:5095;Database=mydb;Protocol=rest"
camus-cli -c "Endpoint=http://localhost:5095"
camus-cli mydb -e "SELECT * FROM users"
camus-cli --diagnose-terminal
CAMUS_FORCE_RICH=1 camus-cli
camus-cli --help
camus-cli --version
Interactive Shell
Primary prompt:
camus>
Multiline continuation prompt:
->
Built-in shell commands:
| Command | Description |
|---|---|
clear | Clear the terminal screen. |
source <path> | Execute SQL from a file. |
use <database> | Switch to another database. |
exit / quit | Exit the shell. |
Examples:
use northwind;
source ./schema.sql
clear
exit
Important guards:
- if a transaction is active,
exitandquitare blocked until youcommitorrollback - if a transaction is active,
use <database>is also blocked
Multiline Input
The shell supports multiline SQL. It keeps collecting input while the statement looks incomplete.
Current incomplete cases include:
- open single-quoted string
- open double-quoted string
- unmatched
( - trailing comma
Example:
select
id,
name
from users
where active = true;
The shell also splits multiple statements on semicolons, while leaving semicolons inside quoted strings alone.
Non-Interactive Execution
Use -e or --execute to run SQL and exit without starting the prompt:
camus-cli northwind -e "SELECT * FROM users"
camus-cli -c "Endpoint=http://localhost:5096;Database=northwind;Protocol=grpc" -e "SHOW TABLES"
Several semicolon-separated statements can run in one call:
camus-cli demo -e "INSERT INTO users (id, name) VALUES (gen_id(), 'Ada'); SELECT * FROM users"
Vertical output also works:
camus-cli demo -e "SELECT * FROM users\G"
This mode is useful for scripts, CI jobs, cron jobs, and shell redirection:
camus-cli demo -e "SELECT * FROM users" > users.txt
History
The shell loads and saves command history automatically.
History file:
camusdb.history.json
It is stored under the system temporary directory.
Behavior from the current source:
- history is loaded on startup
- history is saved on normal exit
- history is also saved on
Ctrl+C - adjacent duplicate entries are removed
- statements that inline passwords with
IDENTIFIED ... BY ...are kept out of the on-disk history file
Keyboard Shortcuts
The enhanced editor supports:
| Key | Action |
|---|---|
Enter | Submit the current statement. |
Shift+Enter | Insert a new line. |
Up / Down | Navigate lines or command history. |
Left / Right | Move the cursor. |
Ctrl+Left / Ctrl+Right | Move by word. |
Home / End | Jump within the current line. |
PageUp / PageDown | Jump to first or last multiline line. |
Backspace / Delete | Delete text. |
Tab | Autocomplete the current word. |
Ctrl+Tab | Cycle to the previous completion. |
SQL Execution
camus-cli routes statements by shape:
- query statements are shown as result tables
- DDL prints
Query OK - inserts, updates, and deletes print affected row counts
Queries include:
select * from users;
explain select * from users;
explain (logical) select * from users;
explain (physical) select * from users;
explain (analyze) select * from users;
show tables;
desc users;
describe users;
show databases;
show columns from users;
describe indexes from users;
show branches from app;
show ancestors from app_test;
DDL includes:
create database app;
create database if not exists app;
show databases;
rename database app to app_prod;
drop database if exists app_prod;
create database app_test branch from app_prod;
create table users (
id oid primary key not null,
name string not null
);
create index users_name_idx on users (name);
alter table users add column active bool default (true);
alter table users rename column name to display_name;
alter table users rename to app_users;
alter table app_users add constraint active_check check (active is not null);
drop table users;
Mutations include:
insert into users (id, name) values (gen_id(), 'Ada');
update users set name = 'A. Lovelace' where id = '...';
delete from users where name = 'A. Lovelace';
Vertical Output
Terminate a query with \G instead of ; to print each row vertically. This is
useful for wide rows, long JSON values, or inspection commands with many
columns.
select * from users\G
Example shape:
*************************** 1. row ***************************
id: 6a3dd713d615ae230488d7f2
name: Ada
1 rows in set (00:00:00.0123456)
\G also works in source files and in batches with multiple statements.
Transactions
The shell has explicit transaction commands:
begin;
commit;
rollback;
It also recognizes:
start transaction;
Rules from the current implementation:
- only one active transaction is allowed at a time
commitwith no active transaction shows an errorrollbackwith no active transaction shows an error- after
commitorrollback, the shell clears its local transaction state - on
Ctrl+C, an active transaction is rolled back before exit
Syntax Highlighting
The interactive editor highlights:
- SQL keywords
- built-in shell commands
- booleans
- quoted strings
- numeric literals
- supported function names
The keyword and function list is embedded in the shell, so it tracks what the CLI knows how to color even if it does not affect server-side SQL support.
The current highlighter includes newer CamusSQL types and keywords such as
UUID, GUID, BYTES, BLOB, DATE, DATETIME, TIMESTAMP, ARRAY,
DATABASES, BRANCH, BRANCHES, ANCESTORS, ISOLATION LEVEL,
READ COMMITTED, SERIALIZABLE, and transaction access keywords.
It also highlights line and block comments:
-- one-line comment
/* block comment */
select gen_uuid_v7(), now();
Autocompletion
Press Tab to autocomplete the word under the cursor. Press Tab again to
cycle forward through matches, or Ctrl+Tab to cycle backward.
Completion is context-aware. After keywords that usually expect a table name,
such as from, into, update, join, table, desc, and describe, the
shell suggests table names from the current database. Elsewhere it suggests SQL
keywords, functions, constants, and shell commands.
select * from us<Tab>
insert into <Tab>
sel<Tab>
Table names are loaded with SHOW TABLES and refreshed on startup, after
use <database>, and after CREATE TABLE or DROP TABLE.
Database Switching
You can change the current database without leaving the shell:
use analytics;
This rewrites the active connection string to replace the Database=... part,
then opens a new connection to that database. The target database must already
exist; use does not create it.
Source Files
Execute a SQL script file:
source ./seed.sql
The shell reads the file, splits statements on semicolons outside quoted strings, and runs them one by one.
Statements terminated with \G inside source files use vertical output.
Workload Subcommand
The CLI also includes a workload helper:
camus-cli workload <init|run> <bank|northwind|factory|tpcc> [options]
Supported workloads:
banknorthwindfactorytpcc
Workload options:
| Option | Description |
|---|---|
-c, --connection-source | Connection string. |
--database | Target database. Default: demo. |
--rows | Rows to generate for init. Default: 1000; used by bank and as the warehouse count for tpcc. |
--concurrency | Parallel workers for run, and parallel writers for init. Default: 64. |
--duration | Run duration in seconds. Default: 60. |
--locking | Transaction locking mode: optimistic or pessimistic. Default: optimistic. |
--isolation | Isolation level: serializable or read-committed. Default: serializable. |
-u, --user | User to authenticate as. Also read from CAMUS_USER. |
-p, --password | Password for -u. Also read from CAMUS_PASSWORD. |
Examples:
camus-cli workload init bank --database demo --rows 5000
camus-cli workload run northwind --concurrency 5 --duration 120
camus-cli workload init factory --database factory
camus-cli workload run factory --concurrency 4 --duration 120
camus-cli workload init tpcc --database tpcc --rows 1
camus-cli workload run tpcc --concurrency 4 --duration 120
If no connection string is supplied, the workload command defaults to:
Endpoint=http://localhost:5096;Database=demo;Protocol=grpc
Endpoint=http://localhost:5095;Database=demo;Protocol=rest
If -c / --connection-source does not include Database=..., the workload
command appends the value from --database.
Like the interactive shell, workloads try gRPC first and REST second unless the
connection string pins Protocol=.... Workloads also set a wider default
command timeout for batched commits.
Terminal Detection
The rich editor is enabled when the terminal reports ANSI support, interactive input, and terminal output. If a capable terminal is not detected correctly, use the diagnostic flag:
camus-cli --diagnose-terminal
Force the rich editor when you know the terminal supports it:
camus-cli --force-rich
or persistently:
export CAMUS_FORCE_RICH=1
Connection Validation
Before the shell opens a connection, it validates that the connection string has:
- a valid absolute
Endpoint
It also performs an initial ping so startup fails early if the target node is not reachable.
When no database is selected, run CREATE DATABASE ... or use <database>
before table-level work.
When To Use It
Use camus-cli when you want:
- a quick interactive SQL session
- easy local development against a CamusDB node
- script execution from
.sqlfiles - manual transaction testing
- lightweight workload bootstrapping for demos and experiments
For application integration, see .NET Driver and EF Core Provider.