From 2053415c765d43a87e14b5d52f580277554d33c6 Mon Sep 17 00:00:00 2001 From: Eli Ribble Date: Wed, 6 May 2026 16:26:38 +0000 Subject: [PATCH] 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. --- generator/metadata/table_meta_data.go | 3 +- generator/template/file_templates.go | 8 +-- generator/template/process.go | 61 ++++++++++++++-------- generator/template/sql_builder_template.go | 40 ++++++++------ 4 files changed, 70 insertions(+), 42 deletions(-) diff --git a/generator/metadata/table_meta_data.go b/generator/metadata/table_meta_data.go index 9533988..e3a117c 100644 --- a/generator/metadata/table_meta_data.go +++ b/generator/metadata/table_meta_data.go @@ -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 diff --git a/generator/template/file_templates.go b/generator/template/file_templates.go index 03c5b83..023ddff 100644 --- a/generator/template/file_templates.go +++ b/generator/template/file_templates.go @@ -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}} } diff --git a/generator/template/process.go b/generator/template/process.go index 493713f..7cdd346 100644 --- a/generator/template/process.go +++ b/generator/template/process.go @@ -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) diff --git a/generator/template/sql_builder_template.go b/generator/template/sql_builder_template.go index 0c4c66c..68cc688 100644 --- a/generator/template/sql_builder_template.go +++ b/generator/template/sql_builder_template.go @@ -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", } }