-
Notifications
You must be signed in to change notification settings - Fork 4
feat: support libpq-compatible environment variables #22
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
Conversation
Add support for standard PostgreSQL libpq environment variables as a fallback when DATABASE_URL is not set: - PGHOST: PostgreSQL server hostname (default: localhost) - PGPORT: PostgreSQL server port (default: 5432) - PGDATABASE: Database name - PGUSER: Username for authentication - PGPASSWORD: Password for authentication - PGSSLMODE: SSL mode (disable, prefer, require, verify-ca, verify-full) The connection priority is now: CLI argument > DATABASE_URL > libpq env vars > config file Special characters in username and password are properly URL-encoded. Closes #21
|
Warning Rate limit exceeded@fcoury has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 2 minutes and 18 seconds before requesting another review. β How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. π¦ How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. π Files selected for processing (1)
WalkthroughAdded a function to construct a PostgreSQL connection URL from libpq-compatible environment variables (PGHOST, PGPORT, PGDATABASE, PGUSER, PGPASSWORD, PGSSLMODE) and integrated it into connection resolution order: CLI arg > DATABASE_URL > libpq env vars > config file. Changes
Estimated code review effortπ― 3 (Moderate) | β±οΈ ~20β25 minutes
Poem
Pre-merge checks and finishing touchesβ Passed checks (5 passed)
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
π§Ή Nitpick comments (2)
crates/tsql/src/main.rs (2)
50-52: Consider using a less aggressive encoding set.
NON_ALPHANUMERICencodes all non-alphanumeric characters, including safe "unreserved" characters like hyphens, underscores, dots, and tildes (per RFC 3986). While this is functional and secure, it produces longer URLs than necessary. For example,user-namebecomesuser%2Dnameinstead of remaininguser-name.If you'd like to optimize, you can define a custom encode set:
use percent_encoding::{AsciiSet, CONTROLS, percent_encode}; // Encode everything except unreserved characters (ALPHA, DIGIT, -, ., _, ~) const USERINFO_ENCODE_SET: &AsciiSet = &CONTROLS .add(b' ').add(b'"').add(b'#').add(b'<').add(b'>').add(b'?') .add(b'`').add(b'{').add(b'}').add(b'/').add(b':').add(b';') .add(b'=').add(b'@').add(b'[').add(b'\\').add(b']').add(b'^') .add(b'|'); // Then use: utf8_percent_encode(u, USERINFO_ENCODE_SET)
371-492: Excellent test coverage with good practices!The test suite is comprehensive and well-structured:
- Correctly uses
#[serial]to prevent race conditions from concurrent env var modifications- Covers key scenarios: defaults, optional fields, special character encoding
- Helper function
clear_libpq_env_vars()ensures clean test stateTo complement the fix for database name encoding, would you like me to generate an additional test case for special characters in database names?
Example test:
#[test] #[serial] fn test_special_characters_in_database() { clear_libpq_env_vars(); env::set_var("PGHOST", "localhost"); env::set_var("PGDATABASE", "my db/test"); let url = build_url_from_libpq_env().unwrap(); // Space and slash should be percent-encoded assert!(url.contains("/my%20db%2Ftest")); }
π Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
π Files selected for processing (1)
crates/tsql/src/main.rs(5 hunks)
π§° Additional context used
π Path-based instructions (1)
**/*.rs
π CodeRabbit inference engine (CLAUDE.md)
**/*.rs: Runcargo fmt --allto format the code before committing changes
Runcargo clippy --all --all-targets -- -D warningsto check for lints and fix them before pushing changes
**/*.rs: Userustfmtwith default settings as the source of truth for code formatting in Rust files
Usesnake_casefor function and module names in Rust
UseCamelCasefor type and trait names in Rust
UseSCREAMING_SNAKE_CASEfor constant names in Rust
Keep changes focused and prefer small, composable helper functions over large UI/app methods
Place unit tests colocated with code using#[cfg(test)]modules for pure logic testing
Files:
crates/tsql/src/main.rs
π§ Learnings (5)
π Common learnings
Learnt from: CR
Repo: fcoury/tsql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-14T16:15:31.051Z
Learning: Run locally using `cargo run -p tsql -- postgres://user:passlocalhost:5432/db` or set `DATABASE_URL` environment variable
Learnt from: CR
Repo: fcoury/tsql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-14T16:15:31.051Z
Learning: Applies to crates/tsql/tests/**/*.rs : Place database-dependent test scenarios in `crates/tsql/tests/` and gate them via `TEST_DATABASE_URL` environment variable
Learnt from: CR
Repo: fcoury/tsql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-14T16:15:31.051Z
Learning: Run integration tests requiring PostgreSQL with `TEST_DATABASE_URL=postgres://postgres:postgreslocalhost:5432/postgres cargo test -p tsql --test integration_tests`
π Learning: 2025-12-14T16:15:31.051Z
Learnt from: CR
Repo: fcoury/tsql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-14T16:15:31.051Z
Learning: Applies to crates/tsql/tests/**/*.rs : Place database-dependent test scenarios in `crates/tsql/tests/` and gate them via `TEST_DATABASE_URL` environment variable
Applied to files:
crates/tsql/src/main.rs
π Learning: 2025-12-14T16:15:31.051Z
Learnt from: CR
Repo: fcoury/tsql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-14T16:15:31.051Z
Learning: Run locally using `cargo run -p tsql -- postgres://user:passlocalhost:5432/db` or set `DATABASE_URL` environment variable
Applied to files:
crates/tsql/src/main.rs
π Learning: 2025-12-14T16:15:31.051Z
Learnt from: CR
Repo: fcoury/tsql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-14T16:15:31.051Z
Learning: Run integration tests requiring PostgreSQL with `TEST_DATABASE_URL=postgres://postgres:postgreslocalhost:5432/postgres cargo test -p tsql --test integration_tests`
Applied to files:
crates/tsql/src/main.rs
π Learning: 2025-12-14T16:15:31.051Z
Learnt from: CR
Repo: fcoury/tsql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-14T16:15:31.051Z
Learning: Run unit tests with `cargo test --lib --bins` for database-free testing
Applied to files:
crates/tsql/src/main.rs
β° Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Test (windows-latest)
π Additional comments (3)
crates/tsql/src/main.rs (3)
10-10: LGTM! Appropriate dependency for URL encoding.The
percent_encodingcrate is the standard choice for URL encoding in Rust, and importingNON_ALPHANUMERICprovides the encoding needed for database credentials.
99-106: LGTM! Clear and comprehensive documentation.The environment variable documentation is well-structured and accurately describes the fallback behavior and default values. The alignment with PostgreSQL's libpq conventions is clearly communicated.
163-173: LGTM! Connection resolution priority is correctly implemented.The updated connection string resolution follows the documented priority (CLI arg β DATABASE_URL β libpq env vars β config file) and uses idiomatic Rust chaining with
.or_else(). The inline comment clearly documents the behavior.
Address PR feedback: - Use custom USERINFO_ENCODE_SET that preserves unreserved characters (-, ., _, ~) per RFC 3986 instead of NON_ALPHANUMERIC - Percent-encode database name to handle special characters like spaces, slashes, and question marks - Add PATH_SEGMENT_ENCODE_SET for database name encoding - Add tests for special characters in database names and verify unreserved characters are not encoded
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
π§Ή Nitpick comments (2)
crates/tsql/src/main.rs (2)
45-67: Consider consolidating duplicate encoding sets.
PATH_SEGMENT_ENCODE_SETandUSERINFO_ENCODE_SETare currently identical. While having separate constants provides flexibility for future divergence, you could consolidate them into a single constant to reduce duplication.-/// Percent-encoding set for URL userinfo (username/password) per RFC 3986. -/// Encodes reserved and unsafe characters while preserving unreserved chars (-, ., _, ~). -const USERINFO_ENCODE_SET: &AsciiSet = &CONTROLS +/// Percent-encoding set for URL components (userinfo and path segments) per RFC 3986. +/// Encodes reserved and unsafe characters while preserving unreserved chars (-, ., _, ~). +const URL_COMPONENT_ENCODE_SET: &AsciiSet = &CONTROLS .add(b' ') .add(b'"') ... - -/// Percent-encoding set for URL path segments (database name) per RFC 3986. -/// Similar to userinfo but also encodes '?' to prevent query string injection. -const PATH_SEGMENT_ENCODE_SET: &AsciiSet = &CONTROLS - .add(b' ') - ...Then update references from
USERINFO_ENCODE_SETandPATH_SEGMENT_ENCODE_SETtoURL_COMPONENT_ENCODE_SET.
109-112: Consider IPv6 host address support.The current implementation doesn't handle IPv6 addresses in PGHOST. IPv6 addresses like "::1" or "2001:db8::1" must be wrapped in brackets in URLs:
postgres://[::1]:5432.You can detect IPv6 addresses by checking for colons:
// Add host and port - url.push_str(&host); - url.push(':'); - url.push_str(&port); + // Wrap IPv6 addresses in brackets + if host.contains(':') { + url.push('['); + url.push_str(&host); + url.push(']'); + } else { + url.push_str(&host); + } + url.push(':'); + url.push_str(&port);This ensures proper URL formatting for both IPv4 and IPv6 addresses.
π Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
π Files selected for processing (1)
crates/tsql/src/main.rs(5 hunks)
π§° Additional context used
π Path-based instructions (1)
**/*.rs
π CodeRabbit inference engine (CLAUDE.md)
**/*.rs: Runcargo fmt --allto format the code before committing changes
Runcargo clippy --all --all-targets -- -D warningsto check for lints and fix them before pushing changes
**/*.rs: Userustfmtwith default settings as the source of truth for code formatting in Rust files
Usesnake_casefor function and module names in Rust
UseCamelCasefor type and trait names in Rust
UseSCREAMING_SNAKE_CASEfor constant names in Rust
Keep changes focused and prefer small, composable helper functions over large UI/app methods
Place unit tests colocated with code using#[cfg(test)]modules for pure logic testing
Files:
crates/tsql/src/main.rs
π§ Learnings (5)
π Common learnings
Learnt from: CR
Repo: fcoury/tsql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-14T16:15:31.051Z
Learning: Run locally using `cargo run -p tsql -- postgres://user:passlocalhost:5432/db` or set `DATABASE_URL` environment variable
Learnt from: CR
Repo: fcoury/tsql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-14T16:15:31.051Z
Learning: Applies to crates/tsql/tests/**/*.rs : Place database-dependent test scenarios in `crates/tsql/tests/` and gate them via `TEST_DATABASE_URL` environment variable
Learnt from: CR
Repo: fcoury/tsql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-14T16:15:31.051Z
Learning: Run integration tests requiring PostgreSQL with `TEST_DATABASE_URL=postgres://postgres:postgreslocalhost:5432/postgres cargo test -p tsql --test integration_tests`
π Learning: 2025-12-14T16:15:31.051Z
Learnt from: CR
Repo: fcoury/tsql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-14T16:15:31.051Z
Learning: Applies to crates/tsql/tests/**/*.rs : Place database-dependent test scenarios in `crates/tsql/tests/` and gate them via `TEST_DATABASE_URL` environment variable
Applied to files:
crates/tsql/src/main.rs
π Learning: 2025-12-14T16:15:31.051Z
Learnt from: CR
Repo: fcoury/tsql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-14T16:15:31.051Z
Learning: Run locally using `cargo run -p tsql -- postgres://user:passlocalhost:5432/db` or set `DATABASE_URL` environment variable
Applied to files:
crates/tsql/src/main.rs
π Learning: 2025-12-14T16:15:31.051Z
Learnt from: CR
Repo: fcoury/tsql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-14T16:15:31.051Z
Learning: Run integration tests requiring PostgreSQL with `TEST_DATABASE_URL=postgres://postgres:postgreslocalhost:5432/postgres cargo test -p tsql --test integration_tests`
Applied to files:
crates/tsql/src/main.rs
π Learning: 2025-12-14T16:15:31.051Z
Learnt from: CR
Repo: fcoury/tsql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-14T16:15:31.051Z
Learning: Run unit tests with `cargo test --lib --bins` for database-free testing
Applied to files:
crates/tsql/src/main.rs
β° Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Test (windows-latest)
π Additional comments (6)
crates/tsql/src/main.rs (6)
10-10: LGTM!The import correctly brings in the necessary percent-encoding utilities for URL construction.
21-43: LGTM!The character set correctly encodes URL-reserved and special characters that could cause parsing issues in the userinfo component (username/password).
114-118: LGTM! Database encoding issue resolved.The database name is now properly percent-encoded using
PATH_SEGMENT_ENCODE_SET, addressing the previous review concern about special characters breaking the URL.
147-153: LGTM!The documentation clearly explains the libpq-compatible environment variables and their usage.
211-221: LGTM!The connection resolution logic correctly implements the priority order (CLI arg β DATABASE_URL β libpq env vars β config file) using idiomatic Rust option chaining.
419-566: LGTM! Excellent test coverage.The test suite is comprehensive and well-structured:
- Uses
serial_testto prevent concurrent test interference with environment variables- Covers all major scenarios including edge cases (special characters, missing values, defaults)
- Helper function
clear_libpq_env_vars()ensures test isolation- Tests verify both URL construction and proper percent-encoding
Address PR feedback: - Consolidate USERINFO_ENCODE_SET and PATH_SEGMENT_ENCODE_SET into single URL_COMPONENT_ENCODE_SET to reduce duplication - Add &, ', and + to encode set for proper query string handling - Percent-encode sslmode value to handle non-standard values - Wrap IPv6 addresses in brackets for proper URL formatting - Add tests for IPv6 addresses (::1, 2001:db8::1) and sslmode encoding
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
π§Ή Nitpick comments (1)
crates/tsql/src/main.rs (1)
52-112: Solid implementation that addresses previous review concerns.The function correctly handles libpq environment variables with appropriate defaults, URL encoding, and IPv6 support. The encoding of database names and sslmode values addresses the issues raised in previous reviews.
Consider validating that
PGPORTis numeric for clearer error messages:let host = env::var("PGHOST").ok(); let port = env::var("PGPORT").ok(); + // Validate port is numeric if provided + if let Some(ref p) = port { + if p.parse::<u16>().is_err() { + return None; + } + } let database = env::var("PGDATABASE").ok();
π Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
π Files selected for processing (1)
crates/tsql/src/main.rs(5 hunks)
π§° Additional context used
π Path-based instructions (1)
**/*.rs
π CodeRabbit inference engine (CLAUDE.md)
**/*.rs: Runcargo fmt --allto format the code before committing changes
Runcargo clippy --all --all-targets -- -D warningsto check for lints and fix them before pushing changes
**/*.rs: Userustfmtwith default settings as the source of truth for code formatting in Rust files
Usesnake_casefor function and module names in Rust
UseCamelCasefor type and trait names in Rust
UseSCREAMING_SNAKE_CASEfor constant names in Rust
Keep changes focused and prefer small, composable helper functions over large UI/app methods
Place unit tests colocated with code using#[cfg(test)]modules for pure logic testing
Files:
crates/tsql/src/main.rs
π§ Learnings (5)
π Common learnings
Learnt from: CR
Repo: fcoury/tsql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-14T16:15:31.051Z
Learning: Run locally using `cargo run -p tsql -- postgres://user:passlocalhost:5432/db` or set `DATABASE_URL` environment variable
Learnt from: CR
Repo: fcoury/tsql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-14T16:15:31.051Z
Learning: Applies to crates/tsql/tests/**/*.rs : Place database-dependent test scenarios in `crates/tsql/tests/` and gate them via `TEST_DATABASE_URL` environment variable
Learnt from: CR
Repo: fcoury/tsql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-14T16:15:31.051Z
Learning: Run integration tests requiring PostgreSQL with `TEST_DATABASE_URL=postgres://postgres:postgreslocalhost:5432/postgres cargo test -p tsql --test integration_tests`
π Learning: 2025-12-14T16:15:31.051Z
Learnt from: CR
Repo: fcoury/tsql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-14T16:15:31.051Z
Learning: Applies to crates/tsql/tests/**/*.rs : Place database-dependent test scenarios in `crates/tsql/tests/` and gate them via `TEST_DATABASE_URL` environment variable
Applied to files:
crates/tsql/src/main.rs
π Learning: 2025-12-14T16:15:31.051Z
Learnt from: CR
Repo: fcoury/tsql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-14T16:15:31.051Z
Learning: Run locally using `cargo run -p tsql -- postgres://user:passlocalhost:5432/db` or set `DATABASE_URL` environment variable
Applied to files:
crates/tsql/src/main.rs
π Learning: 2025-12-14T16:15:31.051Z
Learnt from: CR
Repo: fcoury/tsql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-14T16:15:31.051Z
Learning: Run integration tests requiring PostgreSQL with `TEST_DATABASE_URL=postgres://postgres:postgreslocalhost:5432/postgres cargo test -p tsql --test integration_tests`
Applied to files:
crates/tsql/src/main.rs
π Learning: 2025-12-14T16:15:31.051Z
Learnt from: CR
Repo: fcoury/tsql PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-14T16:15:31.051Z
Learning: Run unit tests with `cargo test --lib --bins` for database-free testing
Applied to files:
crates/tsql/src/main.rs
β° Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Test (macos-latest)
- GitHub Check: Test (windows-latest)
π Additional comments (5)
crates/tsql/src/main.rs (5)
10-10: LGTM!The percent_encoding imports are appropriate for the URL construction functionality.
21-46: Well-designed encoding set that addresses previous concerns.The custom
URL_COMPONENT_ENCODE_SETis appropriately conservative and safely handles all URL component contexts (userinfo, path, query). The implementation correctly preserves unreserved characters (-, ., _, ~) as verified by the test at line 540.
132-138: LGTM!The documentation clearly explains the libpq environment variables and their defaults.
196-206: LGTM!The connection resolution correctly implements the documented priority: CLI arg β DATABASE_URL β libpq env vars β config file.
404-587: Excellent test coverage!The tests comprehensively cover edge cases including special characters, IPv6 addresses, and various environment variable combinations. The use of
#[serial]andclear_libpq_env_vars()ensures proper test isolation.Verify that the
serial_testcrate is declared inCargo.toml:#!/bin/bash # Check if serial_test is declared as a dev-dependency rg -n "serial_test|serial-test" --type=toml
- Add PGPORT validation to check if value is a valid u16 port number - Return LibpqEnvResult struct with both URL and optional warning message - Display warning in TUI status bar instead of printing to stderr - Add tests for invalid port (non-numeric) and out-of-range port (>65535)
Summary
PGHOST,PGPORT,PGDATABASE,PGUSER,PGPASSWORD,PGSSLMODE)DATABASE_URLis not setConnection priority is now: CLI argument β DATABASE_URL β libpq env vars β config file
Closes #21
Test plan
cargo test --package tsql --bin tsql)cargo fmt --all)cargo clippy --all --all-targets -- -D warnings)PGHOST=localhost PGDATABASE=postgres tsqlconnects successfullyPGUSER=myuser PGPASSWORD='p@ss:word' PGHOST=localhost tsqlhandles special charactersSummary by CodeRabbit
New Features
Documentation
Tests
βοΈ Tip: You can customize this high-level summary in your review settings.