Skip to content

HeliosDB CLI Architecture

HeliosDB CLI Architecture

Overview

The HeliosDB CLI (hsql) is a production-quality interactive shell for HeliosDB, inspired by PostgreSQL’s psql and Oracle’s SQL*Plus. It provides a rich command-line interface with auto-completion, history, multiple output formats, and an intuitive menu system.

Architecture Diagram

┌─────────────────────────────────────────────────────────────┐
│ hsql CLI │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌──────────────┐ ┌────────────┐ │
│ │ main.rs │──────│ repl.rs │──────│ menu.rs │ │
│ │ (Entry) │ │ (REPL Loop) │ │ (Menus) │ │
│ └─────────────┘ └──────────────┘ └────────────┘ │
│ │ │ │ │
│ │ │ │ │
│ ┌──────▼─────────────────────▼─────────────────────▼─────┐ │
│ │ Core Modules │ │
│ ├─────────────────────────────────────────────────────────┤ │
│ │ │ │
│ │ ┌─────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ commands.rs │ │ formatter.rs │ │connection.rs │ │ │
│ │ │ (Backslash) │ │ (Output) │ │ (DB Pool) │ │ │
│ │ └─────────────┘ └──────────────┘ └──────────────┘ │ │
│ │ │ │
│ │ ┌─────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │completer.rs │ │ history.rs │ │shortcuts.rs │ │ │
│ │ │(Auto-comp) │ │ (History) │ │ (Keyboard) │ │ │
│ │ └─────────────┘ └──────────────┘ └──────────────┘ │ │
│ │ │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │ │
└──────────────────────────────┼────────────────────────────────┘
┌──────────▼──────────┐
│ HeliosDB Server │
│ (TCP/gRPC) │
└─────────────────────┘

Module Breakdown

1. main.rs - Entry Point

Responsibility: Command-line argument parsing and application initialization

Key Components:

  • Args struct: Defines CLI arguments using clap
  • Connection URL building
  • Mode selection (interactive, menu, batch, single-command)
  • Logging initialization

Flow:

main() -> Parse Args -> Build URL -> Create REPL -> Run Mode

2. repl.rs - REPL Loop

Responsibility: Main read-eval-print loop and session management

Key Components:

  • Repl struct: Main REPL state
  • Interactive loop with rustyline
  • Multi-line query buffering
  • Command routing (SQL vs backslash)
  • Output redirection
  • Timing management

Features:

  • Welcome banner
  • Prompt customization
  • Multi-line SQL support
  • History integration
  • Error handling
  • Session state management

3. commands.rs - Backslash Commands

Responsibility: Parse and execute backslash commands

Key Components:

  • BackslashCommand enum: All supported commands
  • CommandHandler: Command execution logic
  • Query builders for system tables

Command Categories:

  1. General: \q, \?, \!
  2. Query: \i, \o, \timing, \watch
  3. Display: \x, \format
  4. Database: \l, \d, \dt, \di, \dv, \du
  5. HeliosDB: \shards, \replicas, \metadata, \vault, \encryption, \perf

4. formatter.rs - Output Formatting

Responsibility: Format query results in different output modes

Key Components:

  • OutputFormat enum: Table, CSV, JSON
  • Formatter struct: Format engine
  • Table rendering with prettytable-rs
  • Expanded display mode

Features:

  • Colored output
  • Column alignment
  • CSV escaping
  • JSON serialization
  • Expanded (vertical) display

5. connection.rs - Database Connection

Responsibility: Manage database connections and query execution

Key Components:

  • ConnectionManager: Connection pooling
  • QueryResult: Standard result format
  • Mock query execution (for demo)

Features:

  • Connection pooling
  • URL parsing
  • Query execution
  • Result mapping
  • Error handling

Note: Current implementation uses mock data for demonstration. In production, this would integrate with actual database drivers (sqlx, tokio-postgres, etc.).

6. completer.rs - Auto-completion

Responsibility: Provide intelligent auto-completion

Key Components:

  • HeliosCompleter: Implements rustyline’s Completer trait
  • Keyword database
  • Table name cache
  • Command completion

Completion Types:

  1. SQL keywords (SELECT, FROM, WHERE, etc.)
  2. Table names
  3. Column names (future)
  4. Backslash commands
  5. File paths (future)

7. history.rs - Command History

Responsibility: Manage persistent command history

Key Components:

  • HistoryManager: History file management
  • Platform-specific paths
  • History persistence

Storage Locations:

  • Linux: ~/.local/share/heliosdb/hsql_history
  • macOS: ~/Library/Application Support/heliosdb/hsql_history
  • Windows: %APPDATA%\heliosdb\hsql_history

8. shortcuts.rs - Keyboard Shortcuts

Responsibility: Handle keyboard shortcuts and custom key bindings

Key Components:

  • ShortcutAction enum: Action types
  • ShortcutHandler: Key event processing

Shortcuts:

  • Ctrl+A: Move to beginning
  • Ctrl+E: Move to end
  • Ctrl+L: Clear screen
  • Ctrl+D: Exit
  • Ctrl+R: Reverse search
  • Tab: Auto-complete

9. menu.rs - Interactive Menu System

Responsibility: Provide GUI-like menu navigation

Key Components:

  • MenuSystem: Menu engine
  • Hierarchical menu structure
  • Interactive navigation

Menu Structure:

Main Menu
├── Database Objects
│ ├── List Tables
│ ├── Describe Table
│ ├── List Indexes
│ └── List Vector Indexes
├── Cluster Status
│ ├── Show Shards
│ ├── Show Replicas
│ └── Show Metadata
├── Performance Monitoring
│ ├── Show Metrics
│ ├── Query Throughput
│ └── Cache Statistics
├── Security & Vault
│ ├── Show Vault Realms
│ ├── Encryption Status
│ └── Audit Logs
├── Vector Search
│ ├── List Vector Indexes
│ └── ANN Performance
└── Maintenance
├── Run Compaction
├── Create Backup
└── Rotate Keys

Data Flow

SQL Query Execution

User Input
REPL.readline()
Multi-line buffer
ConnectionManager.query()
Database Server
QueryResult
Formatter.format()
Output (stdout/file)

Backslash Command Execution

User Input (\command)
BackslashCommand.parse()
CommandHandler.handle()
├─► System Query
│ │
│ ▼
│ QueryResult
├─► Direct Action
│ (toggle, file I/O)
└─► Menu System
Menu.run()

Dependencies

Core Dependencies

  • tokio: Async runtime
  • anyhow: Error handling
  • serde/serde_json: Serialization

CLI Dependencies

  • rustyline: Readline functionality
  • clap: Argument parsing
  • prettytable-rs: Table formatting
  • crossterm: Terminal control
  • colored: Color output
  • dialoguer: Interactive prompts

Database Dependencies

  • sqlx: SQL database driver (future)
  • url: URL parsing

Design Patterns

1. Command Pattern

Backslash commands use the command pattern for extensibility:

enum BackslashCommand {
ListTables,
DescribeTable(String),
// ...
}
impl CommandHandler {
fn handle(&self, cmd: BackslashCommand) -> Result<()> {
match cmd {
BackslashCommand::ListTables => self.list_tables(),
// ...
}
}
}

2. Strategy Pattern

Output formatting uses strategy pattern:

enum OutputFormat {
Table,
Csv,
Json,
}
impl Formatter {
fn format(&self, result: &QueryResult) -> Result<String> {
match self.format {
OutputFormat::Table => self.format_table(result),
OutputFormat::Csv => self.format_csv(result),
OutputFormat::Json => self.format_json(result),
}
}
}

3. Builder Pattern

Connection manager uses builder pattern:

ConnectionManager::new(url)
.with_timeout(Duration::from_secs(30))
.with_pool_size(10)
.connect()?

Error Handling

All errors use anyhow::Result for flexibility:

pub async fn execute_sql(&mut self, query: &str) -> Result<()> {
let result = self.connection.query(query)
.context("Failed to execute query")?;
let output = self.formatter.format(&result)
.context("Failed to format result")?;
println!("{}", output);
Ok(())
}

Testing Strategy

Unit Tests

  • Command parsing
  • Output formatting
  • Keyboard shortcuts
  • URL parsing

Integration Tests

  • REPL workflow
  • Menu navigation
  • File I/O
  • History persistence

Mock Testing

Current implementation uses mock data for testing without database:

impl ConnectionManager {
fn mock_query_execution(&self, sql: &str) -> Result<QueryResult> {
// Return mock data based on query pattern
}
}

Performance Considerations

1. Connection Pooling

Reuse connections across queries to avoid overhead:

struct ConnectionManager {
pool: Pool<Connection>,
}

2. Lazy Loading

Auto-completion data loaded on-demand:

impl HeliosCompleter {
fn load_tables_if_needed(&mut self) -> Result<()> {
if self.tables.is_empty() {
self.tables = self.fetch_tables()?;
}
Ok(())
}
}

3. Buffered Output

Large results use buffered I/O:

let mut writer = BufWriter::new(file);
for row in result.rows {
writeln!(writer, "{}", format_row(&row))?;
}

Security Considerations

1. Password Masking

Passwords in connection URLs are never displayed:

fn display_connection_info(&self) {
let url = self.url.replace(r":[^@]+@", ":****@");
println!("Connected to: {}", url);
}

2. SQL Injection Prevention

Use parameterized queries (future):

connection.query_with_params(
"SELECT * FROM users WHERE id = $1",
&[user_id],
)?;

3. File Permission Checks

History files use restrictive permissions:

use std::os::unix::fs::PermissionsExt;
let mut perms = fs::metadata(&path)?.permissions();
perms.set_mode(0o600); // Read/write for owner only
fs::set_permissions(&path, perms)?;

Future Enhancements

1. Real Database Connectivity

Integrate with actual HeliosDB protocol:

  • gRPC client implementation
  • Connection pooling
  • Transaction support
  • Prepared statements

2. Advanced Auto-completion

  • Column name completion
  • JOIN clause completion
  • Syntax-aware completion
  • Context-aware suggestions

3. Query Editor

  • Multi-line editor (vim/emacs mode)
  • Syntax highlighting
  • Query history replay
  • Query templates

4. Enhanced Menu System

  • Graphical dashboard (TUI)
  • Real-time metrics
  • Interactive charts
  • Alert notifications

5. Scripting Support

  • Lua/Python integration
  • Custom commands
  • Macros
  • Automation scripts

Conclusion

The HeliosDB CLI provides a powerful, user-friendly interface for database interaction. Its modular architecture allows for easy extension and maintenance, while its rich feature set makes it suitable for both interactive use and automation.