bun

package
v1.0.48 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 30, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

README

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
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
# Generate Bun models from a DBML schema (default: resolvespec types)
relspec convert --from dbml --from-path schema.dbml \
  --to bun --to-path models.go --package models

# Use standard library database/sql nullable types instead of resolvespec
relspec convert --from dbml --from-path schema.dbml \
  --to bun --to-path models.go --package models \
  --types stdlib

# Explicitly select resolvespec types (same as omitting --types)
relspec convert --from pgsql --from-conn "postgres://localhost/mydb" \
  --to bun --to-path models.go --package models \
  --types resolvespec

# Multi-file output (one file per table)
relspec convert --from json --from-path schema.json \
  --to bun --to-path models/ --package models

Generated Code Examples

Default — resolvespec types (--types resolvespec)
package models

import (
    resolvespec_common "github.com/bitechdev/ResolveSpec/pkg/spectypes"
    "github.com/uptrace/bun"
)

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

    ID        int64                              `bun:"id,type:uuid,pk," json:"id"`
    Username  string                             `bun:"username,type:text,notnull," json:"username"`
    Email     resolvespec_common.SqlString       `bun:"email,type:text,nullzero," json:"email"`
    Tags      resolvespec_common.SqlStringArray  `bun:"tags,type:text[],default:'{}',notnull," json:"tags"`
    CreatedAt resolvespec_common.SqlTimeStamp    `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
}
Standard library — --types stdlib
package models

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

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

    ID        string         `bun:"id,type:uuid,pk," json:"id"`
    Username  string         `bun:"username,type:text,notnull," json:"username"`
    Email     sql.NullString `bun:"email,type:text,nullzero," json:"email"`
    Tags      []string       `bun:"tags,type:text[],default:'{}',notnull," json:"tags"`
    CreatedAt time.Time      `bun:"created_at,type:timestamptz,default:now(),notnull," json:"created_at"`
}

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

The nullable type package is selected with --types (or WriterOptions.NullableTypes).

SQL Type NOT NULL (both) Nullable — resolvespec Nullable — stdlib
bigint int64 SqlInt64 sql.NullInt64
integer int32 SqlInt32 sql.NullInt32
smallint int16 SqlInt16 sql.NullInt16
text, varchar string SqlString sql.NullString
boolean bool SqlBool sql.NullBool
timestamp, timestamptz time.Time* SqlTimeStamp sql.NullTime
numeric, decimal float64 SqlFloat64 sql.NullFloat64
uuid string SqlUUID sql.NullString
jsonb string SqlJSONB sql.NullString
text[] SqlStringArray SqlStringArray []string
integer[] SqlInt32Array SqlInt32Array []int32
uuid[] SqlUUIDArray SqlUUIDArray []string
vector SqlVector SqlVector []float32

* In resolvespec mode, NOT NULL timestamps use SqlTimeStamp (not time.Time) unless the base type is a simple integer or boolean. In stdlib mode, NOT NULL timestamps use time.Time.

Writer Options

NullableTypes

Controls which Go package is used for nullable column types. Set via the --types CLI flag or WriterOptions.NullableTypes:

// Use resolvespec types (default — omit NullableTypes or set to "resolvespec")
options := &writers.WriterOptions{
    OutputPath:    "models.go",
    PackageName:   "models",
    NullableTypes: writers.NullableTypeResolveSpec,
}

// Use standard library database/sql types
options := &writers.WriterOptions{
    OutputPath:    "models.go",
    PackageName:   "models",
    NullableTypes: writers.NullableTypeStdlib,
}
Metadata Options
options := &writers.WriterOptions{
    OutputPath:  "models.go",
    PackageName: "models",
    Metadata: map[string]any{
        "multi_file":          true, // Enable multi-file mode
        "populate_refs":       true, // Populate RefDatabase/RefSchema
        "generate_get_id_str": true, // Generate GetIDStr() methods
    },
}

Notes

  • Model names are derived from table names (singularized, PascalCase)
  • Table aliases are auto-generated from table names
  • Nullable columns use resolvespec_common.SqlString, resolvespec_common.SqlTimeStamp, etc. by default; pass --types stdlib to use sql.NullString, sql.NullTime, etc. instead
  • Array columns use resolvespec_common.SqlStringArray, resolvespec_common.SqlInt32Array, etc. by default; --types stdlib produces plain Go slices ([]string, []int32, …)
  • Multi-file mode: one file per table named sql_{schema}_{table}.go
  • Generated code is auto-formatted
  • JSON tags are automatically added

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GeneratePrefix

func GeneratePrefix(tableName string) string

GeneratePrefix generates a 3-letter prefix from a table name Examples: process → PRO, mastertask → MTL, user → USR

func PascalCaseToSnakeCase

func PascalCaseToSnakeCase(s string) string

PascalCaseToSnakeCase converts PascalCase to snake_case Examples: UserID → user_id, HTTPRequest → http_request

func Pluralize

func Pluralize(s string) string

Pluralize converts a singular word to plural Basic implementation with common rules

func Singularize

func Singularize(s string) string

Singularize converts a plural word to singular Basic implementation with common rules

func SnakeCaseToCamelCase

func SnakeCaseToCamelCase(s string) string

SnakeCaseToCamelCase converts snake_case to camelCase Examples: user_id → userID, http_request → httpRequest

func SnakeCaseToPascalCase

func SnakeCaseToPascalCase(s string) string

SnakeCaseToPascalCase converts snake_case to PascalCase Examples: user_id → UserID, http_request → HTTPRequest

Types

type FieldData

type FieldData struct {
	Name    string // Go field name (PascalCase)
	Type    string // Go type
	BunTag  string // Complete bun tag
	JSONTag string // JSON tag
	Comment string // Field comment
}

FieldData represents a single field in a struct

type MethodConfig

type MethodConfig struct {
	GenerateTableName     bool
	GenerateSchemaName    bool
	GenerateTableNameOnly bool
	GenerateGetID         bool
	GenerateGetIDStr      bool
	GenerateSetID         bool
	GenerateUpdateID      bool
	GenerateGetIDName     bool
	GenerateGetPrefix     bool
}

MethodConfig controls which helper methods to generate

func DefaultMethodConfig

func DefaultMethodConfig() *MethodConfig

DefaultMethodConfig returns a MethodConfig with all methods enabled

func LoadMethodConfigFromMetadata

func LoadMethodConfigFromMetadata(metadata map[string]interface{}) *MethodConfig

LoadMethodConfigFromMetadata loads method configuration from metadata map

type ModelData

type ModelData struct {
	Name            string
	TableName       string // schema.table format
	SchemaName      string
	TableNameOnly   string // just table name without schema
	Comment         string
	Fields          []*FieldData
	Config          *MethodConfig
	PrimaryKeyField string // Name of the primary key field
	PrimaryKeyIsSQL bool   // Whether PK uses SQL type (needs .Int64() call)
	IDColumnName    string // Name of the ID column in database
	Prefix          string // 3-letter prefix
}

ModelData represents a single model/struct in the template

func NewModelData

func NewModelData(table *models.Table, schema string, typeMapper *TypeMapper, flattenSchema bool) *ModelData

NewModelData creates a new ModelData from a models.Table

func (*ModelData) AddRelationshipField

func (md *ModelData) AddRelationshipField(field *FieldData)

AddRelationshipField adds a relationship field to the model

type TemplateData

type TemplateData struct {
	PackageName string
	Imports     []string
	Models      []*ModelData
	Config      *MethodConfig
}

TemplateData represents the data passed to the template for code generation

func NewTemplateData

func NewTemplateData(packageName string, config *MethodConfig) *TemplateData

NewTemplateData creates a new TemplateData with the given package name and config

func (*TemplateData) AddImport

func (td *TemplateData) AddImport(importPath string)

AddImport adds an import to the template data (deduplicates automatically)

func (*TemplateData) AddModel

func (td *TemplateData) AddModel(model *ModelData)

AddModel adds a model to the template data

func (*TemplateData) FinalizeImports

func (td *TemplateData) FinalizeImports()

FinalizeImports sorts and organizes imports

type Templates

type Templates struct {
	// contains filtered or unexported fields
}

Templates holds the parsed templates

func NewTemplates

func NewTemplates() (*Templates, error)

NewTemplates creates and parses the templates

func (*Templates) GenerateCode

func (t *Templates) GenerateCode(data *TemplateData) (string, error)

GenerateCode executes the template with the given data

type TypeMapper

type TypeMapper struct {
	// contains filtered or unexported fields
}

TypeMapper handles type conversions between SQL and Go types for Bun

func NewTypeMapper

func NewTypeMapper(typeStyle string) *TypeMapper

NewTypeMapper creates a new TypeMapper. typeStyle should be writers.NullableTypeResolveSpec or writers.NullableTypeStdlib; an empty string defaults to resolvespec.

func (*TypeMapper) BuildBunTag

func (tm *TypeMapper) BuildBunTag(column *models.Column, table *models.Table) string

BuildBunTag generates a complete Bun tag string for a column Bun format: bun:"column_name,type:type_name,pk,default:value"

func (*TypeMapper) BuildRelationshipTag

func (tm *TypeMapper) BuildRelationshipTag(constraint *models.Constraint, relType string) string

BuildRelationshipTag generates Bun tag for relationship fields Bun format: bun:"rel:has-one,join:local_column=foreign_column"

func (*TypeMapper) GetBunImport

func (tm *TypeMapper) GetBunImport() string

GetBunImport returns the import path for Bun

func (*TypeMapper) GetNullableTypeImportLine added in v1.0.48

func (tm *TypeMapper) GetNullableTypeImportLine() string

GetNullableTypeImportLine returns the full Go import line for the nullable type package (ready to pass to AddImport). Returns empty string when no import is needed.

func (*TypeMapper) GetSQLTypesImport

func (tm *TypeMapper) GetSQLTypesImport() string

GetSQLTypesImport returns the import path for the ResolveSpec spectypes package.

func (*TypeMapper) NeedsFmtImport

func (tm *TypeMapper) NeedsFmtImport(generateGetIDStr bool) bool

NeedsFmtImport checks if we need fmt import (for GetIDStr method)

func (*TypeMapper) NeedsTimeImport

func (tm *TypeMapper) NeedsTimeImport(goType string) bool

NeedsTimeImport checks if the Go type requires time package import

func (*TypeMapper) SQLTypeToGoType

func (tm *TypeMapper) SQLTypeToGoType(sqlType string, notNull bool) string

SQLTypeToGoType converts a SQL type to its Go equivalent.

type Writer

type Writer struct {
	// contains filtered or unexported fields
}

Writer implements the writers.Writer interface for Bun models

func NewWriter

func NewWriter(options *writers.WriterOptions) *Writer

NewWriter creates a new Bun writer with the given options

func (*Writer) WriteDatabase

func (w *Writer) WriteDatabase(db *models.Database) error

WriteDatabase writes a complete database as Bun models

func (*Writer) WriteSchema

func (w *Writer) WriteSchema(schema *models.Schema) error

WriteSchema writes a schema as Bun models

func (*Writer) WriteTable

func (w *Writer) WriteTable(table *models.Table) error

WriteTable writes a single table as a Bun model

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL