sqlx-code-review
SKILL.md
sqlx Code Review
Review Workflow
- Check Cargo.toml — Note sqlx features (
runtime-tokio,tls-rustls/tls-native-tls,postgres/mysql/sqlite,uuid,chrono,json,migrate) - Check query patterns — Compile-time checked (
query!,query_as!) vs runtime (query,query_as) - Check pool configuration — Connection limits, timeouts, idle settings
- Check migrations — File naming, reversibility, data migration safety
- Check type mappings — Rust types align with SQL column types
Output Format
Report findings as:
[FILE:LINE] ISSUE_TITLE
Severity: Critical | Major | Minor | Informational
Description of the issue and why it matters.
Quick Reference
| Issue Type | Reference |
|---|---|
| Query macros, bind parameters, result mapping | references/queries.md |
| Migrations, pool config, transaction patterns | references/migrations.md |
Review Checklist
Query Patterns
- Compile-time checked queries (
query!,query_as!) used where possible -
sqlx.tomlorDATABASE_URLconfigured for offline compile-time checking - No string interpolation in queries (SQL injection risk) — use bind parameters (
$1,$2) -
query_as!maps to named structs, not anonymous records, for public APIs -
.fetch_one(),.fetch_optional(),.fetch_all()chosen appropriately -
.fetch()(streaming) used for large result sets
Connection Pool
-
PgPoolshared viaArcor framework state (not created per-request) - Pool size configured for the deployment (not left at defaults in production)
- Connection acquisition timeout set
- Idle connection cleanup configured
Transactions
-
pool.begin()used for multi-statement operations - Transaction committed explicitly (not relying on implicit rollback on drop)
- Errors within transactions trigger rollback before propagation
- Nested transactions use savepoints (
tx.begin()) if needed
Type Mapping
-
sqlx::Typederives match database column types - Enum representations consistent between Rust, serde, and SQL
-
Uuid,DateTime<Utc>,Decimaltypes used (not strings for structured data) -
Option<T>used for nullable columns -
serde_json::Valueused for JSONB columns
Migrations
- Migration files follow naming convention (
YYYYMMDDHHMMSS_description.sql) - Destructive migrations (DROP, ALTER DROP COLUMN) are reversible or have data backup plan
- No data-dependent schema changes in same migration as data changes
-
sqlx::migrate!()called at application startup
Severity Calibration
Critical
- String interpolation in SQL queries (SQL injection)
- Missing transaction for multi-statement writes (partial writes on error)
- Connection pool created per-request (connection exhaustion)
- Missing bind parameter escaping
Major
- Runtime queries (
query()) where compile-time (query!()) could verify correctness - Missing transaction rollback on error paths
- Enum type mismatch between Rust and database
- Unbounded
.fetch_all()on potentially large tables
Minor
- Pool defaults used in production without tuning
- Missing
.fetch_optional()(using.fetch_one()then handling error for "not found") - Overly broad
SELECT *when only specific columns needed - Missing indexes for queried columns (flag only if query pattern is clearly slow)
Informational
- Suggestions to use
query_as!for type-safe result mapping - Suggestions to add database-level constraints alongside Rust validation
- Migration organization improvements
Valid Patterns (Do NOT Flag)
- Runtime
query()for dynamic queries — Compile-time checking doesn't work with dynamic SQL sqlx::FromRowderive — Valid alternative toquery_as!for reusable row typesTEXTcolumns for enum storage — Valid withsqlx::Typederive, simpler than custom SQL types.execute()ignoring row count — Acceptable for idempotent operations (upserts, deletes)- Shared DB with other languages — e.g., Elixir owns migrations, Rust reads. This is a valid architecture.
Before Submitting Findings
Load and follow beagle-rust:review-verification-protocol before reporting any issue.
Weekly Installs
1
Repository
existential-birds/beagleGitHub Stars
40
First Seen
4 days ago
Security Audits
Installed on
mcpjam1
claude-code1
replit1
junie1
windsurf1
zencoder1