Skip to content

Commit 426aae9

Browse files
author
Faycal Bououza
committed
feat(cli): redesign connection flags and free -d for --database
1 parent 0cc59db commit 426aae9

File tree

2 files changed

+5
-134
lines changed

2 files changed

+5
-134
lines changed

README.md

Lines changed: 3 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ A simple, powerful and efficient CLI tool to export PostgreSQL query results to
1616
- [📊 Output Formats](#-output-formats)
1717
- [🔍 Verbose Mode](#-verbose-mode)
1818
- [📄 Format Details](#-format-details)
19-
- [🗃️ Project Structure](#️-project-structure)
20-
- [🧩 Architecture](#-architecture)
2119
- [🛠️ Development](#️-development)
2220
- [🔒 Security](#-security)
2321
- [🚨 Error Handling](#-error-handling)
@@ -150,7 +148,7 @@ pgxport [command] [flags]
150148
| `--format` | `-f` | Output format (csv, json, xml, sql) | `csv` | No |
151149
| `--time-format` | `-T` | Custom date/time format | `yyyy-MM-dd HH:mm:ss` | No |
152150
| `--time-zone` | `-Z` | Time zone for date/time conversion | Local | No |
153-
| `--delimiter` | `-d` | CSV delimiter character | `,` | No |
151+
| `--delimiter` | `-D` | CSV delimiter character | `,` | No |
154152
| `--no-header` | - | Skip CSV header row in output | `false` | No |
155153
| `--with-copy` | - | Use PostgreSQL native COPY for CSV export (faster for large datasets) | `false` | No |
156154
| `--xml-root-tag` | - | Sets the root element name for XML exports | `results` | No |
@@ -201,7 +199,7 @@ _* Either `--sql` or `--sqlfile` must be provided (but not both)_
201199
pgxport -s "SELECT * FROM users WHERE active = true" -o users.csv
202200

203201
# Export with semicolon delimiter
204-
pgxport -s "SELECT id, name, email FROM users" -o users.csv -d ';'
202+
pgxport -s "SELECT id, name, email FROM users" -o users.csv -D ';'
205203

206204
# Skip header row with --no-header
207205
pgxport -s "SELECT id, name, email FROM users" -o users.csv -f csv --no-header
@@ -383,7 +381,7 @@ LEFT JOIN orders o ON u.id = o.user_id
383381
GROUP BY u.id, u.username
384382
HAVING COUNT(o.id) > 0
385383
ORDER BY total_revenue DESC
386-
" -o user_stats.csv -d ','
384+
" -o user_stats.csv -D ','
387385

388386
# Export with timestamp in filename
389387
pgxport -s "SELECT * FROM logs WHERE created_at > NOW() - INTERVAL '24 hours'" \
@@ -622,133 +620,6 @@ INSERT INTO "users" ("id", "name", "email", "created_at") VALUES
622620
-**NULL handling**: NULL values exported as SQL `NULL` keyword
623621
-**Ready to import**: Generated SQL can be directly executed on any PostgreSQL database
624622

625-
## 🗃️ Project Structure
626-
627-
```
628-
pgxport/
629-
├── cmd/ # CLI entry points
630-
│ ├── root.go # Main command + flags
631-
│ ├── root_test.go
632-
│ └── version.go # Version subcommand
633-
634-
├── core/ # Business logic
635-
│ ├── exporter/ # Export formats (pluggable)
636-
│ │ ├── registry.go # Format registration system
637-
│ │ ├── formatting.go # Shared formatting utilities
638-
│ │ ├── compression.go # Compression support (gzip/zip)
639-
│ │ ├── options.go # Export options struct
640-
│ │ ├── testing_helpers.go
641-
│ │ ├── csv_exporter.go # CSV export implementation
642-
│ │ ├── json_exporter.go # JSON export implementation
643-
│ │ ├── xml_exporter.go # XML export implementation
644-
│ │ └── sql_exporter.go # SQL export implementation
645-
│ │
646-
│ ├── db/ # Database operations
647-
│ │ ├── connection.go # PostgreSQL connection management
648-
│ │ └── connection_test.go
649-
│ │
650-
│ ├── config/ # Configuration management
651-
│ │ ├── config.go # Config loading with validation
652-
│ │ └── config_test.go
653-
│ │
654-
│ └── validation/ # Input validation
655-
│ ├── query_safety.go # Query and parameter validation
656-
│ └── query_safety_test.go
657-
658-
├── internal/ # Private packages
659-
│ ├── logger/ # Logging utilities
660-
│ │ └── logger.go # Structured logging with verbose mode
661-
│ └── version/ # Build information
662-
│ └── version.go # Version, BuildTime, GitCommit
663-
664-
├── main.go # Application entry point
665-
├── go.mod # Go module definition
666-
├── go.sum # Go module checksums
667-
├── Taskfile.yml # Build automation
668-
├── LICENSE # MIT license
669-
└── README.md # This file
670-
```
671-
672-
## 🧩 Architecture
673-
674-
The project follows a clean, layered architecture with clear separation of concerns:
675-
676-
```mermaid
677-
flowchart TD
678-
A[CLI - Cobra] --> B[cmd/root.go<br/>Command Handler]
679-
B --> C[core/config<br/>Configuration]
680-
B --> D[core/db<br/>DB Connection]
681-
B --> E[core/exporter<br/>Export Logic]
682-
683-
E --> E0[registry.go<br/>Format Registry]
684-
E0 --> E1[CSV Exporter]
685-
E0 --> E2[JSON Exporter]
686-
E0 --> E3[XML Exporter]
687-
E0 --> E4[SQL Exporter]
688-
689-
E --> F[formatting.go<br/>Shared Utils]
690-
E --> G[compression.go<br/>gzip/zip]
691-
692-
B --> H[internal/logger<br/>Logging]
693-
B --> I[internal/version<br/>Build Info]
694-
695-
D --> J[core/validation<br/>Query Safety]
696-
697-
style B fill:#e1f5ff
698-
style E fill:#ffe1f5
699-
style D fill:#f5ffe1
700-
style C fill:#fff4e1
701-
```
702-
703-
**Architecture Principles:**
704-
705-
- **Layered Structure**: Clear separation between CLI, business logic, and utilities
706-
- **Pluggable Exporters**: Registry pattern allows easy addition of new formats
707-
- **SOLID Principles**: Each package has a single, well-defined responsibility
708-
- **Testability**: Modular design facilitates comprehensive testing
709-
710-
**Component Descriptions:**
711-
712-
### CLI Layer (`cmd/`)
713-
- **`root.go`**: Main command orchestration with Cobra framework
714-
- **`version.go`**: Version information subcommand
715-
716-
### Core Business Logic (`core/`)
717-
718-
**`exporter/`** - Export format implementations
719-
- **`registry.go`**: Dynamic format registration using factory pattern
720-
- **`formatting.go`**: Shared formatting utilities (dates, escaping, etc.)
721-
- **`compression.go`**: Output compression (gzip, zip)
722-
- **`options.go`**: Export configuration options
723-
- **`csv_exporter.go`**: CSV format with COPY mode support
724-
- **`json_exporter.go`**: JSON array format
725-
- **`xml_exporter.go`**: XML format with customizable tags
726-
- **`sql_exporter.go`**: SQL INSERT statements with batch support
727-
728-
**`db/`** - PostgreSQL operations
729-
- **`connection.go`**: Database connection management and query execution
730-
731-
**`config/`** - Application configuration
732-
- **`config.go`**: Configuration loading with `.env` support and validation
733-
734-
**`validation/`** - Input validation
735-
- **`query_safety.go`**: Query and parameter validation
736-
737-
### Internal Utilities (`internal/`)
738-
739-
**`logger/`** - Structured logging
740-
- **`logger.go`**: Logger implementation with verbose mode support
741-
742-
**`version/`** - Build metadata
743-
- **`version.go`**: Version information set via ldflags during build
744-
745-
### Key Design Patterns
746-
747-
1. **Registry Pattern**: Exporters self-register at init time, enabling dynamic format support
748-
2. **Factory Pattern**: Each export creates a fresh instance, avoiding state sharing
749-
3. **Strategy Pattern**: Exporters implement a common interface for interchangeable behavior
750-
4. **Dependency Injection**: Components receive dependencies rather than creating them
751-
752623
## 🛠️ Development
753624

754625
This section is for developers who want to contribute to pgxport.

cmd/root.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ Supported output formats:
5151
pgxport -s "SELECT * FROM users" -o users.csv
5252
5353
# Export from SQL file with custom delimiter
54-
pgxport -F query.sql -o output.csv -d ";"
54+
pgxport -F query.sql -o output.csv -D ";"
5555
5656
# Use the high-performance COPY mode for large CSV exports
5757
pgxport -s "SELECT * FROM events" -o events.csv -f csv --with-copy
@@ -76,7 +76,7 @@ func init() {
7676
rootCmd.Flags().StringVarP(&format, "format", "f", "csv", "Output format (csv, json, xml, sql)")
7777
rootCmd.Flags().StringVarP(&timeFormat, "time-format", "T", "yyyy-MM-dd HH:mm:ss", "Custom time format (e.g. yyyy-MM-ddTHH:mm:ss.SSS)")
7878
rootCmd.Flags().StringVarP(&timeZone, "time-zone", "Z", "", "Time zone for date/time formatting (e.g. UTC, Europe/Paris). Defaults to local time zone.")
79-
rootCmd.Flags().StringVarP(&delimiter, "delimiter", "d", ",", "CSV delimiter character")
79+
rootCmd.Flags().StringVarP(&delimiter, "delimiter", "D", ",", "CSV delimiter character")
8080
rootCmd.Flags().StringVarP(&connString, "dsn", "", "", "Database connection string (postgres://user:pass@host:port/dbname)")
8181
rootCmd.Flags().StringVarP(&tableName, "table", "t", "", "Table name for SQL insert exports")
8282
rootCmd.Flags().StringVarP(&compression, "compression", "z", "none", "Compression to apply to the output file (none, gzip, zip)")

0 commit comments

Comments
 (0)