feat: connect to SQLite from the TUI

This commit is contained in:
Valdemar Lorenzen
2026-10-19 12:19:10 +02:00
parent bbc21f96cf
commit af7e8cad25
3 changed files with 282 additions and 32 deletions
+27 -16
View File
@@ -1,4 +1,5 @@
mod app;
mod connection;
mod db;
use std::{error::Error, io::IsTerminal, path::Path, process::ExitCode};
@@ -12,7 +13,7 @@ Usage:
dbdash --sqlite PATH
dbdash --help
With no argument, the connection is read from DATABASE_URL.
With no argument or DATABASE_URL, the in-app connection screen opens.
Prefer the environment variable to keep passwords out of process arguments:
export DATABASE_URL='postgresql://user@localhost:5432/database'
cargo run
@@ -33,6 +34,7 @@ Navigation:
s Toggle rows and column schema
Left/Right Scroll columns (h/l also work)
n/p, PgDn/Up Next / previous 100-row page
c Open the connection screen (Esc keeps the current database)
r Refresh relations and the active relation
q / Ctrl-C Quit
@@ -66,11 +68,12 @@ fn run() -> Result<()> {
}
let sqlite = argument.as_ref().is_some_and(|arg| arg == "--sqlite");
let connection = if sqlite {
args.next()
.ok_or("--sqlite requires a database file path; see dbdash --help")?
Some(
args.next()
.ok_or("--sqlite requires a database file path; see dbdash --help")?,
)
} else {
argument.or_else(|| std::env::var_os("DATABASE_URL"))
.ok_or("set DATABASE_URL, pass a PostgreSQL connection string, or use --sqlite PATH; see dbdash --help")?
};
if args.next().is_some() {
return Err("unexpected extra arguments; see dbdash --help".into());
@@ -78,22 +81,30 @@ fn run() -> Result<()> {
if !std::io::stdin().is_terminal() || !std::io::stdout().is_terminal() {
return Err("an interactive terminal is required; see dbdash --help".into());
}
let database = if sqlite {
db::Database::open_sqlite(Path::new(&connection))?
} else {
db::Database::connect(
connection
.to_str()
.ok_or("connection string must be UTF-8")?,
)?
};
let mut app = app::App::new(database)?;
let database = connection
.map(|connection| {
if sqlite {
db::Database::open_sqlite(Path::new(&connection))
} else {
db::Database::connect(
connection
.to_str()
.ok_or("connection string must be UTF-8")?,
)
}
})
.transpose()?;
let result = (|| {
let mut terminal = ratatui::try_init()?;
app.run(&mut terminal)
crossterm::execute!(std::io::stdout(), crossterm::event::EnableBracketedPaste)?;
connection::run(&mut terminal, database)
})();
let paste_result =
crossterm::execute!(std::io::stdout(), crossterm::event::DisableBracketedPaste);
ratatui::restore();
result
result?;
paste_result?;
Ok(())
}
fn error_text(error: &(dyn Error + 'static)) -> String {