Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cli args for connection options #95

Merged
merged 5 commits into from
Sep 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

49 changes: 42 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,15 @@ repository = "https://github.com/achristmascarl/rainfrog"
authors = ["achristmascarl <[email protected]>"]
build = "build.rs"
license = "MIT"
exclude = [".github/*", "demo.gif", "demo.tape", "00_init.sql", ".git/*", "Makefile", "docker-compose.yml"]
exclude = [
".github/*",
"demo.gif",
"demo.tape",
"00_init.sql",
".git/*",
"Makefile",
"docker-compose.yml",
]

[profile.dev]
opt-level = 2 # very slow on 1, basically as fast as --release on 2
Expand All @@ -19,10 +27,22 @@ lto = "fat"

[dependencies]
better-panic = "0.3.0"
clap = { version = "4.4.5", features = ["derive", "cargo", "wrap_help", "unicode", "string", "unstable-styles"] }
clap = { version = "4.4.5", features = [
"derive",
"cargo",
"wrap_help",
"unicode",
"string",
"unstable-styles",
] }
color-eyre = "0.6.2"
config = "0.14.0"
crossterm = { version = "0.28.0", features = ["libc", "serde", "event-stream", "bracketed-paste"] }
crossterm = { version = "0.28.0", features = [
"libc",
"serde",
"event-stream",
"bracketed-paste",
] }
derive_deref = "1.1.1"
directories = "5.0.1"
futures = "0.3.28"
Expand All @@ -31,11 +51,23 @@ lazy_static = "1.4.0"
libc = "0.2.148"
log = "0.4.20"
pretty_assertions = "1.4.0"
ratatui = { version = "0.28.0", features = ["serde", "macros", "unstable-widget-ref"] }
ratatui = { version = "0.28.0", features = [
"serde",
"macros",
"unstable-widget-ref",
] }
serde = { version = "1.0.188", features = ["derive"] }
serde_json = "1.0.107"
signal-hook = "0.3.17"
sqlx = { version = "0.8.1", features = [ "runtime-tokio", "tls-rustls", "postgres", "uuid", "chrono", "json", "ipnetwork" ] }
sqlx = { version = "0.8.1", features = [
"runtime-tokio",
"tls-rustls",
"postgres",
"uuid",
"chrono",
"json",
"ipnetwork",
] }
strip-ansi-escapes = "0.2.0"
strum = { version = "0.26.1", features = ["derive"] }
tokio = { version = "1.32.0", features = ["full"] }
Expand All @@ -49,10 +81,13 @@ chrono-tz = { version = "0.5", default-features = false }
indexmap = "2.2.6"
tui-textarea = { version = "0.6.1", features = ["search"] }
sqlparser = "0.49.0"
arboard = { version = "3.4.1", optional = true, features = ["wayland-data-control"] }
arboard = { version = "3.4.1", optional = true, features = [
"wayland-data-control",
] }
rpassword = "7.3.1"

[build-dependencies]
vergen = { version = "8.2.6", features = [ "build", "git", "gitoxide", "cargo" ]}
vergen = { version = "8.2.6", features = ["build", "git", "gitoxide", "cargo"] }

[features]
default = ["dep:arboard"]
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ profile:

db-up:
PORT=$(port) docker compose up -d --wait
sleep .25
sleep 1

db-down:
PORT=$(port) docker compose kill
Expand Down
27 changes: 24 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,30 @@ curl -LSsf https://raw.githubusercontent.com/achristmascarl/rainfrog/main/instal

## usage

> [!NOTE]
> the `connection_url` must include your credentials for accessing
> the database (ex. `postgres://username:password@localhost:5432/postgres`)
all arguments are optional; you will be prompted to provide any missing information.

```sh
rainfrog
```

### with individual options

if any options are not provided, you will be prompted to input them.
if you do not provide an input, that option will
default to what is in your environment variables.

```sh
rainfrog \
--username <username> \
--host <hostname> \
--port <db_port> \
--database <db_name>
```

### with connection url

the `connection_url` must include all the necessary options for connecting
to the database (ex. `postgres://username:password@localhost:5432/postgres`)

```sh
rainfrog --url $(connection_url)
Expand Down
21 changes: 10 additions & 11 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ use ratatui::{
};
use serde::{Deserialize, Serialize};
use sqlparser::{ast::Statement, keywords::DELETE};
use sqlx::{postgres::Postgres, Either, Transaction};
use sqlx::{
postgres::{PgConnectOptions, Postgres},
Either, Transaction,
};
use tokio::{
sync::{
mpsc::{self},
Expand Down Expand Up @@ -52,7 +55,7 @@ pub struct HistoryEntry {
}

pub struct AppState<'a> {
pub connection_string: String,
pub connection_opts: PgConnectOptions,
pub focus: Focus,
pub query_task: Option<DbTask<'a>>,
pub history: Vec<HistoryEntry>,
Expand All @@ -75,8 +78,6 @@ pub struct QueryResultsWithMetadata {

pub struct App<'a> {
pub config: Config,
pub tick_rate: Option<f64>,
pub frame_rate: Option<f64>,
pub components: Components<'static>,
pub should_quit: bool,
pub last_tick_key_events: Vec<KeyEvent>,
Expand All @@ -87,16 +88,14 @@ pub struct App<'a> {
}

impl<'a> App<'a> {
pub fn new(connection_string: String, tick_rate: Option<f64>, frame_rate: Option<f64>) -> Result<Self> {
pub fn new(connection_opts: PgConnectOptions) -> Result<Self> {
let focus = Focus::Menu;
let menu = Menu::new();
let editor = Editor::new();
let history = History::new();
let data = Data::new();
let config = Config::new()?;
Ok(Self {
tick_rate,
frame_rate,
components: Components {
menu: Box::new(menu),
editor: Box::new(editor),
Expand All @@ -109,7 +108,7 @@ impl<'a> App<'a> {
last_frame_mouse_event: None,
pool: None,
state: AppState {
connection_string,
connection_opts,
focus,
query_task: None,
history: vec![],
Expand All @@ -133,12 +132,12 @@ impl<'a> App<'a> {

pub async fn run(&mut self) -> Result<()> {
let (action_tx, mut action_rx) = mpsc::unbounded_channel();
let connection_url = self.state.connection_string.clone();
let pool = database::init_pool(connection_url).await?;
let connection_opts = self.state.connection_opts.clone();
let pool = database::init_pool(connection_opts).await?;
log::info!("{pool:?}");
self.pool = Some(pool);

let mut tui = tui::Tui::new()?.tick_rate(self.tick_rate).frame_rate(self.frame_rate);
let mut tui = tui::Tui::new()?;
tui.enter()?;

self.components.menu.register_action_handler(action_tx.clone())?;
Expand Down
27 changes: 18 additions & 9 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,29 @@ use clap::Parser;

use crate::utils::version;

#[derive(Parser, Debug)]
#[derive(Parser, Debug, Clone)]
#[command(author, version = version(), about)]
pub struct Cli {
#[arg(short, long, value_name = "FLOAT", help = "Tick rate, i.e. number of ticks per second")]
pub tick_rate: Option<f64>,

#[arg(short, long, value_name = "FLOAT", help = "Frame rate, i.e. number of frames per second")]
pub frame_rate: Option<f64>,

#[arg(
short = 'u',
long = "url",
value_name = "URL",
help = "Connection URL for the database, e.g. postgres://username:password@localhost:5432/dbname"
help = "Full connection URL for the database, e.g. postgres://username:password@localhost:5432/dbname"
)]
pub connection_url: String,
pub connection_url: Option<String>,

#[arg(long = "username", value_name = "USERNAME", help = "Username for database connection")]
pub user: Option<String>,

#[arg(long = "password", value_name = "PASSWORD", help = "Password for database connection")]
pub password: Option<String>,

#[arg(long = "host", value_name = "HOST", help = "Host for database connection (ex. localhost)")]
pub host: Option<String>,

#[arg(long = "port", value_name = "PORT", help = "Port for database connection (ex. 5432)")]
pub port: Option<u16>,

#[arg(long = "database", value_name = "DATABASE", help = "Name of database for connection (ex. postgres)")]
pub database: Option<String>,
}
9 changes: 6 additions & 3 deletions src/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ use sqlparser::{
parser::{Parser, ParserError},
};
use sqlx::{
postgres::{PgColumn, PgPool, PgPoolOptions, PgQueryResult, PgRow, PgTypeInfo, PgTypeKind, PgValueRef, Postgres},
postgres::{
PgColumn, PgConnectOptions, PgPool, PgPoolOptions, PgQueryResult, PgRow, PgTypeInfo, PgTypeKind, PgValueRef,
Postgres,
},
types::Uuid,
Column, Database, Either, Error, Pool, Row, Transaction, ValueRef,
};
Expand All @@ -34,8 +37,8 @@ pub type Headers = Vec<Header>;
pub type DbPool = PgPool;
pub type DbError = sqlx::Either<Error, ParserError>;

pub async fn init_pool(url: String) -> Result<PgPool, Error> {
PgPoolOptions::new().max_connections(5).connect(&url).await
pub async fn init_pool(opts: PgConnectOptions) -> Result<PgPool, Error> {
PgPoolOptions::new().max_connections(5).connect_with(opts).await
}

// since it's possible for raw_sql to execute multiple queries in a single string,
Expand Down
Loading