Files
gormcol/README.md

278 lines
6.6 KiB
Markdown

# gormcol
Type-safe GORM column descriptors and model generation utilities.
## Library
The library provides [Field](#field) for type-safe column references and methods to extract column/table names.
### Field
`Field` represents a GORM column descriptor with table context. Generated code creates package-level variables with typed field references:
```go
var ProductCols = struct {
ID gormcol.Field
Name gormcol.Field
Price gormcol.Field
}{
ID: gormcol.Field{}.Set((&Product{}).TableName(), "id_product"),
Name: gormcol.Field{}.Set((&Product{}).TableName(), "name"),
Price: gormcol.Field{}.Set((&Product{}).TableName(), "price"),
}
```
### Field Methods
#### TabCol
Returns "table.column" format for use in SQL with table qualification.
```go
model.ProductCols.Price.TabCol() // "ps_product.price"
```
#### Col
Returns just the column name.
```go
model.ProductCols.Price.Col() // "price"
```
#### Tab
Returns the table name.
```go
model.ProductCols.Price.Tab() // "ps_product"
```
## CLI
The `cmd/` directory contains a standalone tool that generates GORM model files with column descriptors.
### Install
```bash
go install git.ma-al.com/goc_marek/gormcol/cmd/gormcol@latest
```
Or from source:
```bash
go install ./cmd/gormcol
```
### Prerequisites
- [fzf](https://github.com/junegunn/fzf) - required for interactive mode (optional for `--all`)
### Usage
```
gormcol [options]
```
DSN can be provided via `--dsn` flag or `DSN` env var (from `.env` file).
**Modes:**
- **Interactive (default)**: select tables with fzf
- **Batch (`--filter` or `--all`)**: generate matching tables with confirmation
| Flag | Default | Description |
|-----------|------------------------|---------------------------------------------------|
| `--dsn` | *(from DSN env)* | MySQL/MariaDB DSN, e.g. `user:pass@tcp(localhost:3306)/dbname` |
| `--filter`| *(interactive)* | Regex matching table names to generate (triggers batch mode) |
| `--all` | *(interactive)* | Generate all tables matching filter (shows confirmation) |
| `--out` | `./app/model/dbmodel` | Output directory for generated files |
| `--pkg` | `dbmodel` | Go package name for generated files |
| `--clean` | false | Remove existing model files before generation |
### Interactive Mode (Default)
Without flags, the tool launches an interactive table selector:
```bash
gormcol --dsn "user:pass@tcp(localhost:3306)/mydb"
```
Features:
- **Fuzzy search** as you type
- **Tab** - toggle table selection (multi-select)
- **Enter** - confirm selection
- **Esc** - cancel
### Batch Mode (--filter)
Use `--filter` to generate all tables matching a regex pattern:
```bash
gormcol --dsn "user:pass@tcp(localhost:3306)/mydb" --filter "ps_product.*"
```
### Generate All Tables (--all)
Use `--all` to generate all tables matching the default filter `(ps_|b2b_).*`:
```bash
gormcol --dsn "user:pass@tcp(localhost:3306)/mydb" --all
```
A confirmation prompt appears:
```
WARNING: Generate all 325 tables? [Enter] confirm / [Esc] cancel
```
- **Enter** - confirm and generate
- **Esc** - cancel
### Example
```bash
./gormcol --dsn "user:pass@tcp(localhost:3306)/mydb" --filter "ps_.*" --out ./internal/model --pkg model
```
This connects to the database, generates a `.go` model file for each matching table, and appends `<Model>Cols` variables with typed `gormcol.Field` descriptors to each file.
### Configuration File (.env)
Create a `.env` file in your project root for default values:
```env
# Database connection
DSN=user:pass@tcp(localhost:3306)/mydb
# Table filter (regex)
FILTER=(ps_|b2b_).*
# Output settings
OUT=./app/model/dbmodel
PKG=dbmodel
```
Command-line flags override `.env` values.
## Library Functions Reference
### ConnectDSN
Opens a MySQL/MariaDB connection from a DSN string.
```go
db, err := gormcol.ConnectDSN("user:pass@tcp(localhost:3306)/dbname")
```
### New
Creates a new GormGen with default configuration.
```go
gg := gormcol.New(db)
```
### NewWithConfig
Creates a new GormGen with custom configuration.
```go
gg := gormcol.NewWithConfig(db, gormcol.GenConfig{
OutputDir: "./models",
PkgName: "models",
TableFilter: "ps_.*",
})
```
### GenModels
Generates GORM model files and column descriptors for matched tables.
```go
ctx := context.Background()
err := gg.GenModels(ctx)
```
## GenConfig
Configuration for model generation.
| Field | Default | Description |
|-----------------|--------------------------|---------------------------------------------------|
| `OutputDir` | `./app/model/dbmodel` | Directory for generated files |
| `PkgName` | `dbmodel` | Go package name |
| `TableFilter` | `ps_.*` | Regex pattern to match table names |
| `SelectedTables`| *(none)* | Specific tables to generate (overrides filter) |
| `Clean` | `true` | Remove existing files before generation |
## Generated Models
After generation, each model file contains a struct and a `Cols` variable:
```go
// model/product.go
type Product struct {
ID uint `gorm:"column:id_product;primaryKey"`
Name string `gorm:"column:name"`
Price float32 `gorm:"column:price;type:decimal(20,6)"`
}
var ProductCols = struct {
ID gormcol.Field
Name gormcol.Field
Price gormcol.Field
}{
ID: gormcol.Field{}.Set((&Product{}).TableName(), "id_product"),
Name: gormcol.Field{}.Set((&Product{}).TableName(), "name"),
Price: gormcol.Field{}.Set((&Product{}).TableName(), "price"),
}
```
## Using Generated Models
### Table-qualified columns
Use `TabCol()` for table-qualified column references:
```go
import "git.ma-al.com/goc_marek/gormcol"
// Where clauses
db.Where(
model.ProductCols.Price.TabCol() + " > ?",
100.0,
).Find(&products)
// Order
db.Order(model.ProductCols.Name.TabCol() + " ASC").Find(&products)
// Joins
db.Joins("JOIN ps_category ON " +
model.ProductCols.ID.TabCol() + " = ps_category.id_product",
).Find(&products)
```
### Unqualified column names
Use `Col()` when the table is already scoped:
```go
db.Select(model.ProductCols.Name.Col()).Find(&products)
// Raw queries
db.Raw("SELECT " + model.ProductCols.Name.Col() + " FROM ps_product").Scan(&names)
```
### Table name
Use `Tab()` to get the table name from a column descriptor:
```go
table := model.ProductCols.ID.Tab() // "ps_product"
```
## Dependencies
- `gorm.io/gorm`
- `gorm.io/gen`
- `gorm.io/driver/mysql`