Skip to main content

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:

CodeMeaning
CADB0516Not authenticated: missing, invalid, expired, or rejected credentials.
CADB0517Authenticated, but missing a privilege on a table touched by the statement, including joins and subqueries.
CADB0519The 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:

OptionDescription
[database]Optional database name. If omitted, the shell starts without a selected database.
-c, --connection-sourceFull connection string. If it has no Database=..., the shell starts without a selected database.
-e, --executeExecute one SQL string and exit instead of starting the interactive shell.
-u, --userUser to authenticate as.
-p, --passwordPassword for -u. If omitted in interactive use, the shell prompts.
--tokenUse an existing bearer token instead of logging in with a password.
--force-richForce the rich editor on terminals whose capabilities are not detected automatically.
--diagnose-terminalPrint terminal capability detection details and exit.
-h, --helpShow help.
-v, --versionShow version.

Environment variables:

VariableDescription
CAMUS_FORCE_RICHSet to 1, true, or yes to force the rich editor.
CAMUS_USERDefault for -u.
CAMUS_PASSWORDDefault for -p. Useful in scripts because it keeps the password out of the process command line.
CAMUS_ACCESS_TOKENDefault 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:

CommandDescription
clearClear the terminal screen.
source <path>Execute SQL from a file.
use <database>Switch to another database.
exit / quitExit the shell.

Examples:

use northwind;
source ./schema.sql
clear
exit

Important guards:

  • if a transaction is active, exit and quit are blocked until you commit or rollback
  • 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:

KeyAction
EnterSubmit the current statement.
Shift+EnterInsert a new line.
Up / DownNavigate lines or command history.
Left / RightMove the cursor.
Ctrl+Left / Ctrl+RightMove by word.
Home / EndJump within the current line.
PageUp / PageDownJump to first or last multiline line.
Backspace / DeleteDelete text.
TabAutocomplete the current word.
Ctrl+TabCycle 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
  • commit with no active transaction shows an error
  • rollback with no active transaction shows an error
  • after commit or rollback, 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:

  • bank
  • northwind
  • factory
  • tpcc

Workload options:

OptionDescription
-c, --connection-sourceConnection string.
--databaseTarget database. Default: demo.
--rowsRows to generate for init. Default: 1000; used by bank and as the warehouse count for tpcc.
--concurrencyParallel workers for run, and parallel writers for init. Default: 64.
--durationRun duration in seconds. Default: 60.
--lockingTransaction locking mode: optimistic or pessimistic. Default: optimistic.
--isolationIsolation level: serializable or read-committed. Default: serializable.
-u, --userUser to authenticate as. Also read from CAMUS_USER.
-p, --passwordPassword 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 .sql files
  • manual transaction testing
  • lightweight workload bootstrapping for demos and experiments

For application integration, see .NET Driver and EF Core Provider.