263 lines
6.0 KiB
Markdown
263 lines
6.0 KiB
Markdown
# gormcol
|
|
|
|
Type-safe GORM column descriptors and model generation utilities.
|
|
|
|
## Library
|
|
|
|
The library provides [Field](#field) for type-safe column references and helper functions to extract column/table names.
|
|
|
|
### Field
|
|
|
|
`Field` represents a GORM column descriptor with table context. Define package-level variables to get type-safe column references:
|
|
|
|
```go
|
|
var PsAccess = struct {
|
|
IDProfile gormcol.Field
|
|
IDAuthorizationRole gormcol.Field
|
|
}{
|
|
IDProfile: gormcol.Field{Table: "ps_access", Column: "id_profile"},
|
|
IDAuthorizationRole: gormcol.Field{Table: "ps_access", Column: "id_authorization_role"},
|
|
}
|
|
```
|
|
|
|
### Helper Functions
|
|
|
|
#### Column
|
|
|
|
Returns just the column name from a Field descriptor.
|
|
|
|
```go
|
|
gormcol.Column(dbmodel.PsAccess.IDAuthorizationRole) // "id_authorization_role"
|
|
```
|
|
|
|
#### ColumnOnTable
|
|
|
|
Returns "table.column" format from a Field descriptor.
|
|
|
|
```go
|
|
gormcol.ColumnOnTable(dbmodel.PsAccess.IDAuthorizationRole) // "ps_access.id_authorization_role"
|
|
```
|
|
|
|
#### TableField
|
|
|
|
Returns the table name from a Field descriptor.
|
|
|
|
```go
|
|
gormcol.TableField(dbmodel.PsAccess.IDAuthorizationRole) // "ps_access"
|
|
```
|
|
|
|
## 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 |
|
|
|
|
### 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)
|
|
```
|
|
|
|
## 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 Field
|
|
Name Field
|
|
Price Field
|
|
}{
|
|
ID: Field{Table: "ps_product", Column: "id_product"},
|
|
Name: Field{Table: "ps_product", Column: "name"},
|
|
Price: Field{Table: "ps_product", Column: "price"},
|
|
}
|
|
```
|
|
|
|
## Using Generated Models
|
|
|
|
### GORM queries with type-safe columns
|
|
|
|
Use `ColumnOnTable` for table-qualified column references in GORM clauses:
|
|
|
|
```go
|
|
import "git.ma-al.com/goc_marek/gormcol"
|
|
|
|
// Where clauses
|
|
db.Where(
|
|
gormcol.ColumnOnTable(model.ProductCols.Price) + " > ?",
|
|
100.0,
|
|
).Find(&products)
|
|
|
|
// Order
|
|
db.Order(gormcol.ColumnOnTable(model.ProductCols.Name) + " ASC").Find(&products)
|
|
|
|
// Joins
|
|
db.Joins("JOIN ps_category ON " +
|
|
gormcol.ColumnOnTable(model.ProductCols.ID) + " = ps_category.id_product",
|
|
).Find(&products)
|
|
```
|
|
|
|
### Unqualified column names
|
|
|
|
Use `Column` when the table is already scoped:
|
|
|
|
```go
|
|
db.Select(gormcol.Column(model.ProductCols.Name)).Find(&products)
|
|
|
|
// Raw queries
|
|
db.Raw("SELECT " + gormcol.Column(model.ProductCols.Name) + " FROM ps_product").Scan(&names)
|
|
```
|
|
|
|
### Table name
|
|
|
|
Use `TableField` to get the table name from a column descriptor:
|
|
|
|
```go
|
|
table := gormcol.TableField(model.ProductCols.ID) // "ps_product"
|
|
```
|
|
|
|
## Dependencies
|
|
|
|
- `gorm.io/gorm`
|
|
- `gorm.io/gen`
|
|
- `gorm.io/driver/mysql`
|