2021-07-27 17:39:21 +02:00
|
|
|
package template
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"github.com/go-jet/jet/v2/generator/metadata"
|
2023-07-21 14:11:31 +02:00
|
|
|
"github.com/go-jet/jet/v2/internal/utils/dbidentifier"
|
2021-07-27 17:39:21 +02:00
|
|
|
"path"
|
2021-10-21 13:21:01 +02:00
|
|
|
"strings"
|
2021-07-27 17:39:21 +02:00
|
|
|
"unicode"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// SQLBuilder is template for generating sql builder files
|
|
|
|
|
type SQLBuilder struct {
|
|
|
|
|
Skip bool
|
|
|
|
|
Path string
|
|
|
|
|
Table func(table metadata.Table) TableSQLBuilder
|
|
|
|
|
View func(view metadata.Table) TableSQLBuilder
|
|
|
|
|
Enum func(enum metadata.Enum) EnumSQLBuilder
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DefaultSQLBuilder returns default SQLBuilder implementation
|
|
|
|
|
func DefaultSQLBuilder() SQLBuilder {
|
|
|
|
|
return SQLBuilder{
|
|
|
|
|
Path: "",
|
|
|
|
|
Table: DefaultTableSQLBuilder,
|
|
|
|
|
View: DefaultViewSQLBuilder,
|
|
|
|
|
Enum: DefaultEnumSQLBuilder,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UsePath returns new SQLBuilder with new relative path set
|
|
|
|
|
func (sb SQLBuilder) UsePath(path string) SQLBuilder {
|
|
|
|
|
sb.Path = path
|
|
|
|
|
return sb
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UseTable returns new SQLBuilder with new TableSQLBuilder template function set
|
|
|
|
|
func (sb SQLBuilder) UseTable(tableFunc func(table metadata.Table) TableSQLBuilder) SQLBuilder {
|
|
|
|
|
sb.Table = tableFunc
|
|
|
|
|
return sb
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UseView returns new SQLBuilder with new ViewSQLBuilder template function set
|
|
|
|
|
func (sb SQLBuilder) UseView(viewFunc func(table metadata.Table) ViewSQLBuilder) SQLBuilder {
|
|
|
|
|
sb.View = viewFunc
|
|
|
|
|
return sb
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UseEnum returns new SQLBuilder with new EnumSQLBuilder template function set
|
|
|
|
|
func (sb SQLBuilder) UseEnum(enumFunc func(enum metadata.Enum) EnumSQLBuilder) SQLBuilder {
|
|
|
|
|
sb.Enum = enumFunc
|
|
|
|
|
return sb
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TableSQLBuilder is template for generating table SQLBuilder files
|
|
|
|
|
type TableSQLBuilder struct {
|
|
|
|
|
Skip bool
|
|
|
|
|
Path string
|
|
|
|
|
FileName string
|
|
|
|
|
InstanceName string
|
|
|
|
|
TypeName string
|
2023-08-02 10:03:59 +09:00
|
|
|
DefaultAlias string
|
2021-07-27 17:39:21 +02:00
|
|
|
Column func(columnMetaData metadata.Column) TableSQLBuilderColumn
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ViewSQLBuilder is template for generating view SQLBuilder files
|
|
|
|
|
type ViewSQLBuilder = TableSQLBuilder
|
|
|
|
|
|
|
|
|
|
// DefaultTableSQLBuilder returns default implementation for TableSQLBuilder
|
|
|
|
|
func DefaultTableSQLBuilder(tableMetaData metadata.Table) TableSQLBuilder {
|
2024-02-17 12:46:00 +01:00
|
|
|
tableNameGoIdentifier := dbidentifier.ToGoIdentifier(tableMetaData.Name)
|
|
|
|
|
|
2021-07-27 17:39:21 +02:00
|
|
|
return TableSQLBuilder{
|
|
|
|
|
Path: "/table",
|
2023-07-21 14:11:31 +02:00
|
|
|
FileName: dbidentifier.ToGoFileName(tableMetaData.Name),
|
2024-02-17 12:46:00 +01:00
|
|
|
InstanceName: tableNameGoIdentifier,
|
|
|
|
|
TypeName: tableNameGoIdentifier + "Table",
|
2023-08-02 10:03:59 +09:00
|
|
|
DefaultAlias: "",
|
2021-07-27 17:39:21 +02:00
|
|
|
Column: DefaultTableSQLBuilderColumn,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DefaultViewSQLBuilder returns default implementation for ViewSQLBuilder
|
|
|
|
|
func DefaultViewSQLBuilder(viewMetaData metadata.Table) ViewSQLBuilder {
|
|
|
|
|
tableSQLBuilder := DefaultTableSQLBuilder(viewMetaData)
|
|
|
|
|
tableSQLBuilder.Path = "/view"
|
|
|
|
|
return tableSQLBuilder
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// PackageName returns package name of table sql builder types
|
|
|
|
|
func (tb TableSQLBuilder) PackageName() string {
|
|
|
|
|
return path.Base(tb.Path)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UsePath returns new TableSQLBuilder with new relative path set
|
|
|
|
|
func (tb TableSQLBuilder) UsePath(path string) TableSQLBuilder {
|
|
|
|
|
tb.Path = path
|
|
|
|
|
return tb
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UseFileName returns new TableSQLBuilder with new file name set
|
|
|
|
|
func (tb TableSQLBuilder) UseFileName(name string) TableSQLBuilder {
|
|
|
|
|
tb.FileName = name
|
|
|
|
|
return tb
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UseInstanceName returns new TableSQLBuilder with new instance name set
|
|
|
|
|
func (tb TableSQLBuilder) UseInstanceName(name string) TableSQLBuilder {
|
|
|
|
|
tb.InstanceName = name
|
|
|
|
|
return tb
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UseTypeName returns new TableSQLBuilder with new type name set
|
|
|
|
|
func (tb TableSQLBuilder) UseTypeName(name string) TableSQLBuilder {
|
|
|
|
|
tb.TypeName = name
|
|
|
|
|
return tb
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-02 10:03:59 +09:00
|
|
|
// UseDefaultAlias returns new TableSQLBuilder with new default alias set
|
|
|
|
|
func (tb TableSQLBuilder) UseDefaultAlias(defaultAlias string) TableSQLBuilder {
|
|
|
|
|
tb.DefaultAlias = defaultAlias
|
|
|
|
|
return tb
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-27 17:39:21 +02:00
|
|
|
// UseColumn returns new TableSQLBuilder with new column template function set
|
|
|
|
|
func (tb TableSQLBuilder) UseColumn(columnsFunc func(column metadata.Column) TableSQLBuilderColumn) TableSQLBuilder {
|
|
|
|
|
tb.Column = columnsFunc
|
|
|
|
|
return tb
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TableSQLBuilderColumn is template for table sql builder column
|
|
|
|
|
type TableSQLBuilderColumn struct {
|
|
|
|
|
Name string
|
|
|
|
|
Type string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DefaultTableSQLBuilderColumn returns default implementation of TableSQLBuilderColumn
|
|
|
|
|
func DefaultTableSQLBuilderColumn(columnMetaData metadata.Column) TableSQLBuilderColumn {
|
|
|
|
|
return TableSQLBuilderColumn{
|
2023-07-21 14:11:31 +02:00
|
|
|
Name: dbidentifier.ToGoIdentifier(columnMetaData.Name),
|
2021-07-27 17:39:21 +02:00
|
|
|
Type: getSqlBuilderColumnType(columnMetaData),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// getSqlBuilderColumnType returns type of jet sql builder column
|
|
|
|
|
func getSqlBuilderColumnType(columnMetaData metadata.Column) string {
|
2024-02-01 15:20:49 +01:00
|
|
|
if columnMetaData.DataType.Kind != metadata.BaseType &&
|
|
|
|
|
columnMetaData.DataType.Kind != metadata.RangeType {
|
2021-07-27 17:39:21 +02:00
|
|
|
return "String"
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-21 13:21:01 +02:00
|
|
|
switch strings.ToLower(columnMetaData.DataType.Name) {
|
2024-02-01 15:20:49 +01:00
|
|
|
case "boolean", "bool":
|
2021-07-27 17:39:21 +02:00
|
|
|
return "Bool"
|
2024-02-01 15:20:49 +01:00
|
|
|
case "smallint", "integer", "bigint", "int2", "int4", "int8",
|
2021-07-27 17:39:21 +02:00
|
|
|
"tinyint", "mediumint", "int", "year": //MySQL
|
|
|
|
|
return "Integer"
|
|
|
|
|
case "date":
|
|
|
|
|
return "Date"
|
|
|
|
|
case "timestamp without time zone",
|
|
|
|
|
"timestamp", "datetime": //MySQL:
|
|
|
|
|
return "Timestamp"
|
2024-02-01 15:20:49 +01:00
|
|
|
case "timestamp with time zone", "timestamptz":
|
2021-07-27 17:39:21 +02:00
|
|
|
return "Timestampz"
|
|
|
|
|
case "time without time zone",
|
|
|
|
|
"time": //MySQL
|
|
|
|
|
return "Time"
|
2024-02-01 15:20:49 +01:00
|
|
|
case "time with time zone", "timetz":
|
2021-07-27 17:39:21 +02:00
|
|
|
return "Timez"
|
|
|
|
|
case "interval":
|
|
|
|
|
return "Interval"
|
2021-10-21 13:21:01 +02:00
|
|
|
case "user-defined", "enum", "text", "character", "character varying", "bytea", "uuid",
|
2021-07-27 17:39:21 +02:00
|
|
|
"tsvector", "bit", "bit varying", "money", "json", "jsonb", "xml", "point", "line", "ARRAY",
|
2024-02-01 15:20:49 +01:00
|
|
|
"char", "varchar", "nvarchar", "binary", "varbinary", "bpchar", "varbit",
|
2021-07-27 17:39:21 +02:00
|
|
|
"tinyblob", "blob", "mediumblob", "longblob", "tinytext", "mediumtext", "longtext": // MySQL
|
|
|
|
|
return "String"
|
2024-02-01 15:20:49 +01:00
|
|
|
case "real", "numeric", "decimal", "double precision", "float", "float4", "float8",
|
2021-07-27 17:39:21 +02:00
|
|
|
"double": // MySQL
|
|
|
|
|
return "Float"
|
2024-01-31 15:30:09 +01:00
|
|
|
case "daterange":
|
|
|
|
|
return "DateRange"
|
|
|
|
|
case "tsrange":
|
|
|
|
|
return "TimestampRange"
|
|
|
|
|
case "tstzrange":
|
|
|
|
|
return "TimestampzRange"
|
|
|
|
|
case "int4range":
|
|
|
|
|
return "Int4Range"
|
|
|
|
|
case "int8range":
|
|
|
|
|
return "Int8Range"
|
|
|
|
|
case "numrange":
|
|
|
|
|
return "NumericRange"
|
2021-07-27 17:39:21 +02:00
|
|
|
default:
|
|
|
|
|
fmt.Println("- [SQL Builder] Unsupported sql column '" + columnMetaData.Name + " " + columnMetaData.DataType.Name + "', using StringColumn instead.")
|
|
|
|
|
return "String"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// EnumSQLBuilder is template for generating enum SQLBuilder files
|
|
|
|
|
type EnumSQLBuilder struct {
|
|
|
|
|
Skip bool
|
|
|
|
|
Path string
|
|
|
|
|
FileName string
|
|
|
|
|
InstanceName string
|
|
|
|
|
ValueName func(enumValue string) string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DefaultEnumSQLBuilder returns default implementation of EnumSQLBuilder
|
|
|
|
|
func DefaultEnumSQLBuilder(enumMetaData metadata.Enum) EnumSQLBuilder {
|
|
|
|
|
return EnumSQLBuilder{
|
|
|
|
|
Path: "/enum",
|
2023-07-21 14:11:31 +02:00
|
|
|
FileName: dbidentifier.ToGoFileName(enumMetaData.Name),
|
|
|
|
|
InstanceName: dbidentifier.ToGoIdentifier(enumMetaData.Name),
|
2021-07-27 17:39:21 +02:00
|
|
|
ValueName: func(enumValue string) string {
|
|
|
|
|
return defaultEnumValueName(enumMetaData.Name, enumValue)
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// PackageName returns enum sql builder package name
|
|
|
|
|
func (e EnumSQLBuilder) PackageName() string {
|
|
|
|
|
return path.Base(e.Path)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UsePath returns new EnumSQLBuilder with new path set
|
|
|
|
|
func (e EnumSQLBuilder) UsePath(path string) EnumSQLBuilder {
|
|
|
|
|
e.Path = path
|
|
|
|
|
return e
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UseFileName returns new EnumSQLBuilder with new file name set
|
|
|
|
|
func (e EnumSQLBuilder) UseFileName(name string) EnumSQLBuilder {
|
|
|
|
|
e.FileName = name
|
|
|
|
|
return e
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UseInstanceName returns new EnumSQLBuilder with instance name set
|
|
|
|
|
func (e EnumSQLBuilder) UseInstanceName(name string) EnumSQLBuilder {
|
|
|
|
|
e.InstanceName = name
|
|
|
|
|
return e
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func defaultEnumValueName(enumName, enumValue string) string {
|
2023-07-21 14:11:31 +02:00
|
|
|
enumValueName := dbidentifier.ToGoIdentifier(enumValue)
|
2021-07-27 17:39:21 +02:00
|
|
|
if !unicode.IsLetter([]rune(enumValueName)[0]) {
|
2023-07-21 14:11:31 +02:00
|
|
|
return dbidentifier.ToGoIdentifier(enumName) + enumValueName
|
2021-07-27 17:39:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return enumValueName
|
|
|
|
|
}
|