# Bun Writer

Generates Go source files with Bun model definitions from database schema information.

## Overview

The Bun Writer converts RelSpec's internal database model representation into Go source code with Bun struct definitions, complete with proper tags, relationships, and table configuration.

## Features

- Generates Bun-compatible Go structs
- Creates proper `bun` struct tags
- Adds relationship fields
- Supports both single-file and multi-file output
- Maps SQL types to Go types
- Handles nullable fields with sql.Null* types
- Generates table aliases

## Usage

### Basic Example

```go
package main

import (
    "git.warky.dev/wdevs/relspecgo/pkg/models"
    "git.warky.dev/wdevs/relspecgo/pkg/writers"
    "git.warky.dev/wdevs/relspecgo/pkg/writers/bun"
)

func main() {
    options := &writers.WriterOptions{
        OutputPath:  "models.go",
        PackageName: "models",
    }

    writer := bun.NewWriter(options)
    err := writer.WriteDatabase(db)
    if err != nil {
        panic(err)
    }
}
```

### CLI Examples

```bash
# Generate Bun models from PostgreSQL database
relspec --input pgsql \
  --conn "postgres://localhost/mydb" \
  --output bun \
  --out-file models.go \
  --package models

# Convert GORM models to Bun
relspec --input gorm --in-file gorm_models.go --output bun --out-file bun_models.go

# Multi-file output
relspec --input json --in-file schema.json --output bun --out-file models/
```

## Generated Code Example

```go
package models

import (
    "time"
    "database/sql"
    "github.com/uptrace/bun"
)

type User struct {
    bun.BaseModel `bun:"table:users,alias:u"`

    ID        int64     `bun:"id,pk,autoincrement" json:"id"`
    Username  string    `bun:"username,notnull,unique" json:"username"`
    Email     string    `bun:"email,notnull" json:"email"`
    Bio       sql.NullString `bun:"bio" json:"bio,omitempty"`
    CreatedAt time.Time `bun:"created_at,notnull,default:now()" json:"created_at"`

    // Relationships
    Posts []*Post `bun:"rel:has-many,join:id=user_id" json:"posts,omitempty"`
}

type Post struct {
    bun.BaseModel `bun:"table:posts,alias:p"`

    ID      int64          `bun:"id,pk" json:"id"`
    UserID  int64          `bun:"user_id,notnull" json:"user_id"`
    Title   string         `bun:"title,notnull" json:"title"`
    Content sql.NullString `bun:"content" json:"content,omitempty"`

    // Belongs to
    User *User `bun:"rel:belongs-to,join:user_id=id" json:"user,omitempty"`
}
```

## Supported Bun Tags

- `table` - Table name and alias
- `column` - Column name (auto-derived if not specified)
- `pk` - Primary key
- `autoincrement` - Auto-increment
- `notnull` - NOT NULL constraint
- `unique` - Unique constraint
- `default` - Default value
- `rel` - Relationship definition
- `type` - Explicit SQL type

## Type Mapping

| SQL Type | Go Type | Nullable Type |
|----------|---------|---------------|
| bigint | int64 | sql.NullInt64 |
| integer | int | sql.NullInt32 |
| varchar, text | string | sql.NullString |
| boolean | bool | sql.NullBool |
| timestamp | time.Time | sql.NullTime |
| numeric | float64 | sql.NullFloat64 |

## Notes

- Model names are derived from table names (singularized, PascalCase)
- Table aliases are auto-generated from table names
- Multi-file mode: one file per table named `sql_{schema}_{table}.go`
- Generated code is auto-formatted
- JSON tags are automatically added
