Make it possible to add fully custom columns to table definition

This adds a few different fields to the column SQL builder that were
once either calculated or hard-coded:
 * Import - so you can import the column from anywhere
 * Type - fully, rather than partially, modifiable to allow any naming
   convention
 * TypeFactory - fully, rather than partially defined

I also alphabetized some things because the OCD compels me.
This commit is contained in:
Eli Ribble 2026-05-06 16:26:38 +00:00
parent b30d7c524d
commit 2053415c76
No known key found for this signature in database
4 changed files with 70 additions and 42 deletions

View file

@ -2,9 +2,10 @@ package metadata
// Table metadata struct
type Table struct {
Name string `sql:"primary_key"`
Comment string
Columns []Column
Imports []string
Name string `sql:"primary_key"`
}
// MutableColumns returns list of mutable columns for table

View file

@ -14,7 +14,9 @@ var tableSQLBuilderTemplate = `
package {{package}}
import (
"github.com/go-jet/jet/v2/{{dialect.PackageName}}"
{{- range $i, $import := imports .Columns}}
"{{$import}}"
{{- end}}
)
var {{tableTemplate.InstanceName}} = new{{tableTemplate.TypeName}}("{{schemaName}}", "{{.Name}}", "{{tableTemplate.DefaultAlias}}")
@ -27,7 +29,7 @@ type {{structImplName}} struct {
{{- range $i, $c := .Columns}}
{{- $field := columnField $c}}
{{- if not $field.Skip}}
{{$field.Name}} {{dialect.PackageName}}.Column{{$field.Type}} {{golangComment .Comment}}
{{$field.Name}} {{$field.PackageName}}.{{$field.Type}} {{golangComment .Comment}}
{{- end}}
{{- end}}
@ -74,7 +76,7 @@ func new{{tableTemplate.TypeName}}Impl(schemaName, tableName, alias string) {{st
{{- range $i, $c := .Columns}}
{{- $field := columnField $c}}
{{- if not $field.Skip }}
{{$field.Name}}Column = {{dialect.PackageName}}.{{$field.Type}}Column("{{$c.Name}}")
{{$field.Name}}Column = {{$field.PackageName}}.{{$field.TypeFactory}}("{{$c.Name}}")
{{- end}}
{{- end}}
allColumns = {{dialect.PackageName}}.ColumnList{ {{columnList .Columns}} }

View file

@ -6,6 +6,7 @@ import (
"fmt"
"os"
"path/filepath"
"sort"
"strings"
"text/template"
@ -15,6 +16,7 @@ import (
"github.com/go-jet/jet/v2/internal/jet"
)
type Dialect = jet.Dialect
// ProcessSchema will process schema metadata and constructs go files using generator Template
func ProcessSchema(dirPath string, schemaMetaData metadata.Schema, generatorTemplate Template) error {
if schemaMetaData.IsEmpty() {
@ -194,34 +196,13 @@ func processTableSQLBuilder(fileTypes, dirPath string,
autoGenWarningTemplate+tableSQLBuilderTemplate,
tableMetaData,
template.FuncMap{
"package": func() string {
return tableSQLBuilder.PackageName()
},
"dialect": func() jet.Dialect {
return dialect
},
"schemaName": func() string {
return schemaMetaData.Name
},
"tableTemplate": func() TableSQLBuilder {
return tableSQLBuilder
},
"structImplName": func() string { // postgres only
structName := tableSQLBuilder.TypeName
return string(strings.ToLower(structName)[0]) + structName[1:]
},
"columnField": func(columnMetaData metadata.Column) TableSQLBuilderColumn {
return tableSQLBuilder.Column(columnMetaData)
return tableSQLBuilder.Column(dialect, columnMetaData)
},
"toUpper": strings.ToUpper,
"insertedRowAlias": func() string {
return insertedRowAlias(dialect)
},
"golangComment": formatGolangComment,
"columnList": func(columns []metadata.Column) string {
names := []string{}
for _, col := range columns {
bc := tableSQLBuilder.Column(col)
bc := tableSQLBuilder.Column(dialect, col)
if bc.Skip {
continue
}
@ -229,6 +210,40 @@ func processTableSQLBuilder(fileTypes, dirPath string,
}
return strings.Join(names, ", ")
},
"dialect": func() jet.Dialect {
return dialect
},
"golangComment": formatGolangComment,
"imports": func(columns []metadata.Column) []string {
imports := make(map[string]struct{}, 0)
for _, columnMetaData := range columns {
c := tableSQLBuilder.Column(dialect, columnMetaData)
imports[c.Import] = struct{}{}
}
results := make([]string, 0)
for k, _ := range imports {
results = append(results, k)
}
sort.Strings(results)
return results
},
"insertedRowAlias": func() string {
return insertedRowAlias(dialect)
},
"package": func() string {
return tableSQLBuilder.PackageName()
},
"schemaName": func() string {
return schemaMetaData.Name
},
"structImplName": func() string { // postgres only
structName := tableSQLBuilder.TypeName
return string(strings.ToLower(structName)[0]) + structName[1:]
},
"tableTemplate": func() TableSQLBuilder {
return tableSQLBuilder
},
"toUpper": strings.ToUpper,
})
if err != nil {
return fmt.Errorf("failed to generate table sql builder type %s: %w", tableSQLBuilder.TypeName, err)

View file

@ -8,6 +8,7 @@ import (
"unicode"
"github.com/go-jet/jet/v2/generator/metadata"
"github.com/go-jet/jet/v2/internal/jet"
"github.com/go-jet/jet/v2/internal/utils/dbidentifier"
)
@ -62,13 +63,14 @@ func (sb SQLBuilder) ShouldSkip(skip bool) SQLBuilder {
// TableSQLBuilder is template for generating table SQLBuilder files
type TableSQLBuilder struct {
Skip bool
Path string
FileName string
InstanceName string
TypeName string
Column func(dialect jet.Dialect, columnMetaData metadata.Column) TableSQLBuilderColumn
DefaultAlias string
Column func(columnMetaData metadata.Column) TableSQLBuilderColumn
Imports []string
InstanceName string
FileName string
Path string
Skip bool
TypeName string
}
// ViewSQLBuilder is template for generating view SQLBuilder files
@ -79,12 +81,13 @@ func DefaultTableSQLBuilder(tableMetaData metadata.Table) TableSQLBuilder {
tableNameGoIdentifier := dbidentifier.ToGoIdentifier(tableMetaData.Name)
return TableSQLBuilder{
Path: "/table",
FileName: dbidentifier.ToGoFileName(tableMetaData.Name),
InstanceName: tableNameGoIdentifier,
TypeName: tableNameGoIdentifier + "Table",
DefaultAlias: "",
Column: DefaultTableSQLBuilderColumn,
DefaultAlias: "",
FileName: dbidentifier.ToGoFileName(tableMetaData.Name),
Imports: []string{},
InstanceName: tableNameGoIdentifier,
Path: "/table",
TypeName: tableNameGoIdentifier + "Table",
}
}
@ -131,16 +134,19 @@ func (tb TableSQLBuilder) UseDefaultAlias(defaultAlias string) TableSQLBuilder {
}
// UseColumn returns new TableSQLBuilder with new column template function set
func (tb TableSQLBuilder) UseColumn(columnsFunc func(column metadata.Column) TableSQLBuilderColumn) TableSQLBuilder {
func (tb TableSQLBuilder) UseColumn(columnsFunc func(dialect jet.Dialect, column metadata.Column) TableSQLBuilderColumn) TableSQLBuilder {
tb.Column = columnsFunc
return tb
}
// TableSQLBuilderColumn is template for table sql builder column
type TableSQLBuilderColumn struct {
Skip bool
Import string
Name string
PackageName string
Skip bool
Type string
TypeFactory string
}
var reservedKeywords = []string{"TableName", "Table", "SchemaName", "Alias", "AllColumns", "MutableColumns", "DefaultColumns"}
@ -153,10 +159,14 @@ func renameIfReserved(name string) string {
}
// DefaultTableSQLBuilderColumn returns default implementation of TableSQLBuilderColumn
func DefaultTableSQLBuilderColumn(columnMetaData metadata.Column) TableSQLBuilderColumn {
func DefaultTableSQLBuilderColumn(dialect jet.Dialect, columnMetaData metadata.Column) TableSQLBuilderColumn {
package_name := dialect.PackageName()
return TableSQLBuilderColumn{
Import: "github.com/go-jet/jet/v2/" + package_name,
Name: renameIfReserved(dbidentifier.ToGoIdentifier(columnMetaData.Name)),
Type: getSqlBuilderColumnType(columnMetaData),
PackageName: package_name,
Type: "Column" + getSqlBuilderColumnType(columnMetaData),
TypeFactory: getSqlBuilderColumnType(columnMetaData)+"Column",
}
}