Skip to content

Commit

Permalink
prevent panic in config.toml
Browse files Browse the repository at this point in the history
  • Loading branch information
kyoto7250 committed Jun 27, 2024
1 parent 541ddc5 commit 380cd62
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 80 deletions.
74 changes: 38 additions & 36 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::components::{
use crate::config::Config;
use crate::database::{MySqlPool, Pool, PostgresPool, SqlitePool};
use crate::event::Key;
use anyhow::Context;
use ratatui::layout::Flex;
use ratatui::{
layout::{Constraint, Direction, Layout, Rect},
Expand Down Expand Up @@ -58,13 +59,19 @@ impl App {

pub fn draw(&mut self, f: &mut Frame) -> anyhow::Result<()> {
if let Focus::ConnectionList = self.focus {
self.connections.draw(
match self.connections.draw(
f,
Layout::default()
.constraints([Constraint::Percentage(100)])
.split(f.size())[0],
false,
)?;
) {
Ok(()) => (),
Err(e) => {
return Err(anyhow::anyhow!(e).context("from: ConnectionsComponent::draw"));
}
}

self.error.draw(f, Rect::default(), false)?;
self.help.draw(f, Rect::default(), false)?;
return Ok(());
Expand Down Expand Up @@ -142,40 +149,35 @@ impl App {
pool.close().await;
}

self.pool = if conn.is_mysql() {
Some(Box::new(
MySqlPool::new(
conn.database_url()?.as_str(),
conn.limit_size,
conn.timeout_second,
)
.await?,
))
} else if conn.is_postgres() {
Some(Box::new(
PostgresPool::new(
conn.database_url()?.as_str(),
conn.limit_size,
conn.timeout_second,
)
.await?,
))
} else {
Some(Box::new(
SqlitePool::new(
conn.database_url()?.as_str(),
conn.limit_size,
conn.timeout_second,
)
.await?,
))
};
self.databases
.update(conn, self.pool.as_ref().unwrap())
.await?;
self.focus = Focus::DatabaseList;
self.record_table.reset();
self.tab.reset();
match conn.database_url() {
Ok(url) => {
self.pool = if conn.is_mysql() {
Some(Box::new(
MySqlPool::new(url.as_str(), conn.limit_size, conn.timeout_second)
.await?,
))
} else if conn.is_postgres() {
Some(Box::new(
PostgresPool::new(url.as_str(), conn.limit_size, conn.timeout_second)
.await?,
))
} else {
Some(Box::new(
SqlitePool::new(url.as_str(), conn.limit_size, conn.timeout_second)
.await?,
))
};
self.databases
.update(conn, self.pool.as_ref().unwrap())
.await?;
self.focus = Focus::DatabaseList;
self.record_table.reset();
self.tab.reset();
}
Err(e) => {
return Err(anyhow::anyhow!(e)).context("from Connection::database_url");
}
}
}
Ok(())
}
Expand Down
11 changes: 7 additions & 4 deletions src/components/connections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,13 @@ impl StatefulDrawableComponent for ConnectionsComponent {
let conns = &self.connections;
let mut connections: Vec<ListItem> = Vec::new();
for c in conns {
connections.push(
ListItem::new(vec![Line::from(Span::raw(c.database_url_with_name()?))])
.style(Style::default()),
)
match c.database_url_with_name() {
Ok(url) => connections
.push(ListItem::new(vec![Line::from(Span::raw(url))]).style(Style::default())),
Err(e) => {
return Err(anyhow::anyhow!(e).context("Failed to database_url_with_name"));
}
}
}
let connections = List::new(connections)
.block(Block::default().borders(Borders::ALL).title("Connections"))
Expand Down
82 changes: 46 additions & 36 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,18 +255,21 @@ impl Connection {
fn build_database_url(&self, password: String) -> anyhow::Result<String> {
match self.r#type {
DatabaseType::MySql => {
let user = self
.user
.as_ref()
.ok_or_else(|| anyhow::anyhow!("type mysql needs the user field"))?;
let host = self
.host
.as_ref()
.ok_or_else(|| anyhow::anyhow!("type mysql needs the host field"))?;
let port = self
.port
.as_ref()
.ok_or_else(|| anyhow::anyhow!("type mysql needs the port field"))?;
let user = self.user.as_ref().ok_or_else(|| {
anyhow::anyhow!(
"type mysql needs the user field in Connection::build_database_url"
)
})?;
let host = self.host.as_ref().ok_or_else(|| {
anyhow::anyhow!(
"type mysql needs the host field in Connection::build_database_url"
)
})?;
let port = self.port.as_ref().ok_or_else(|| {
anyhow::anyhow!(
"type mysql needs the port field in Connection::build_database_url"
)
})?;
let unix_domain_socket = self
.valid_unix_domain_socket()
.map_or(String::new(), |uds| format!("?socket={}", uds));
Expand All @@ -292,18 +295,21 @@ impl Connection {
}
}
DatabaseType::Postgres => {
let user = self
.user
.as_ref()
.ok_or_else(|| anyhow::anyhow!("type postgres needs the user field"))?;
let host = self
.host
.as_ref()
.ok_or_else(|| anyhow::anyhow!("type postgres needs the host field"))?;
let port = self
.port
.as_ref()
.ok_or_else(|| anyhow::anyhow!("type postgres needs the port field"))?;
let user = self.user.as_ref().ok_or_else(|| {
anyhow::anyhow!(
"type postgres needs the user field in Connection::build_database_url"
)
})?;
let host = self.host.as_ref().ok_or_else(|| {
anyhow::anyhow!(
"type postgres needs the host field in Connection::build_database_url"
)
})?;
let port = self.port.as_ref().ok_or_else(|| {
anyhow::anyhow!(
"type postgres needs the port field in Connection::build_database_url"
)
})?;

if let Some(unix_domain_socket) = self.valid_unix_domain_socket() {
match self.database.as_ref() {
Expand Down Expand Up @@ -343,9 +349,15 @@ impl Connection {
}
DatabaseType::Sqlite => {
let path = self.path.as_ref().map_or(
Err(anyhow::anyhow!("type sqlite needs the path field")),
Err(anyhow::anyhow!(
"type sqlite needs the path field in Connection::build_database_url"
)),
|path| {
expand_path(path).ok_or_else(|| anyhow::anyhow!("cannot expand file path"))
expand_path(path).ok_or_else(|| {
anyhow::anyhow!(
"cannot expand file path in Connection::build_database_url"
)
})
},
)?;

Expand All @@ -355,16 +367,14 @@ impl Connection {
}

pub fn database_url_with_name(&self) -> anyhow::Result<String> {
let database_url = self.masked_database_url()?;

Ok(match &self.name {
Some(name) => format!(
"[{name}] {database_url}",
name = name,
database_url = database_url
),
None => database_url,
})
match self.masked_database_url() {
Ok(url) => Ok(match &self.name {
Some(name) => format!("[{name}] {database_url}", name = name, database_url = url),
None => url,
}),
Err(e) => Err(anyhow::anyhow!(e)
.context("Failed to masked_database_url in Connection::database_url_with_name")),
}
}

pub fn is_mysql(&self) -> bool {
Expand Down
12 changes: 8 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,25 @@ use std::panic::{set_hook, take_hook};
async fn main() -> anyhow::Result<()> {
let value = crate::cli::parse();
let config = Config::new(&value.config)?;

setup_terminal()?;

let backend = CrosstermBackend::new(io::stdout());
let mut terminal = Terminal::new(backend)?;
let events = event::Events::new(250);
let mut app = App::new(config.clone());

terminal.clear()?;

loop {
terminal.draw(|f| {
if let Err(err) = app.draw(f) {
outln!(config #Error, "error: {}", err.to_string());
shutdown_terminal();
let mut source = err.source();
while let Some(err) = source {
eprintln!("Caused by: {}", err);
source = err.source();
}
eprintln!("Failed by: {}", err);

std::process::exit(1);
}
})?;
Expand All @@ -64,7 +69,6 @@ async fn main() -> anyhow::Result<()> {

shutdown_terminal();
terminal.show_cursor()?;

Ok(())
}

Expand Down

0 comments on commit 380cd62

Please sign in to comment.