Replace invalid character from the go identifiers with description string.

This commit is contained in:
go-jet 2024-02-17 12:46:00 +01:00
parent 255f4a8eaf
commit 6b098b8e41
3 changed files with 135 additions and 7 deletions

View file

@ -68,11 +68,13 @@ type ViewSQLBuilder = TableSQLBuilder
// DefaultTableSQLBuilder returns default implementation for TableSQLBuilder // DefaultTableSQLBuilder returns default implementation for TableSQLBuilder
func DefaultTableSQLBuilder(tableMetaData metadata.Table) TableSQLBuilder { func DefaultTableSQLBuilder(tableMetaData metadata.Table) TableSQLBuilder {
tableNameGoIdentifier := dbidentifier.ToGoIdentifier(tableMetaData.Name)
return TableSQLBuilder{ return TableSQLBuilder{
Path: "/table", Path: "/table",
FileName: dbidentifier.ToGoFileName(tableMetaData.Name), FileName: dbidentifier.ToGoFileName(tableMetaData.Name),
InstanceName: dbidentifier.ToGoIdentifier(tableMetaData.Name), InstanceName: tableNameGoIdentifier,
TypeName: dbidentifier.ToGoIdentifier(tableMetaData.Name) + "Table", TypeName: tableNameGoIdentifier + "Table",
DefaultAlias: "", DefaultAlias: "",
Column: DefaultTableSQLBuilderColumn, Column: DefaultTableSQLBuilderColumn,
} }

View file

@ -3,6 +3,7 @@ package dbidentifier
import ( import (
"github.com/go-jet/jet/v2/internal/3rdparty/snaker" "github.com/go-jet/jet/v2/internal/3rdparty/snaker"
"strings" "strings"
"unicode"
) )
// ToGoIdentifier converts database identifier to Go identifier. // ToGoIdentifier converts database identifier to Go identifier.
@ -15,10 +16,92 @@ func ToGoFileName(databaseIdentifier string) string {
return strings.ToLower(replaceInvalidChars(databaseIdentifier)) return strings.ToLower(replaceInvalidChars(databaseIdentifier))
} }
func replaceInvalidChars(str string) string { func replaceInvalidChars(identifier string) string {
str = strings.Replace(str, " ", "_", -1) increase, needs := needsCharReplacement(identifier)
str = strings.Replace(str, "-", "_", -1)
str = strings.Replace(str, ".", "_", -1)
return str if !needs {
return identifier
}
var b strings.Builder
b.Grow(len(identifier) + increase)
for _, c := range identifier {
switch {
case unicode.IsSpace(c):
b.WriteByte('_')
case unicode.IsControl(c):
continue
default:
replacement, ok := asciiCharacterReplacement[c]
if ok {
b.WriteByte('_')
b.WriteString(replacement)
b.WriteByte('_')
} else {
b.WriteRune(c)
}
}
}
return b.String()
}
func needsCharReplacement(identifier string) (increase int, needs bool) {
for _, c := range identifier {
switch {
case unicode.IsSpace(c):
needs = true
case unicode.IsControl(c):
increase += -1
needs = true
continue
default:
replacement, ok := asciiCharacterReplacement[c]
if ok {
increase += len(replacement) + 1
needs = true
}
}
}
return increase, needs
}
var asciiCharacterReplacement = map[rune]string{
'!': "exclamation",
'"': "quotation",
'#': "number",
'$': "dollar",
'%': "percent",
'&': "ampersand",
'\'': "apostrophe",
'(': "opening_parentheses",
')': "closing_parentheses",
'*': "asterisk",
'+': "plus",
',': "comma",
'-': "_",
'.': "_",
'/': "slash",
':': "colon",
';': "semicolon",
'<': "less",
'=': "equal",
'>': "greater",
'?': "question",
'@': "at",
'[': "opening_bracket",
'\\': "backslash",
']': "closing_bracket",
'^': "caret",
'`': "accent",
'{': "opening_braces",
'|': "vertical_bar",
'}': "closing_braces",
'~': "tilde",
} }

View file

@ -8,6 +8,7 @@ import (
func TestToGoIdentifier(t *testing.T) { func TestToGoIdentifier(t *testing.T) {
require.Equal(t, ToGoIdentifier(""), "") require.Equal(t, ToGoIdentifier(""), "")
require.Equal(t, ToGoIdentifier("uuid"), "UUID") require.Equal(t, ToGoIdentifier("uuid"), "UUID")
require.Equal(t, ToGoIdentifier("uuid_ptr"), "UUIDPtr")
require.Equal(t, ToGoIdentifier("col1"), "Col1") require.Equal(t, ToGoIdentifier("col1"), "Col1")
require.Equal(t, ToGoIdentifier("PG-13"), "Pg13") require.Equal(t, ToGoIdentifier("PG-13"), "Pg13")
require.Equal(t, ToGoIdentifier("13_pg"), "13Pg") require.Equal(t, ToGoIdentifier("13_pg"), "13Pg")
@ -18,8 +19,50 @@ func TestToGoIdentifier(t *testing.T) {
require.Equal(t, ToGoIdentifier("myTaBlE"), "MyTaBlE") require.Equal(t, ToGoIdentifier("myTaBlE"), "MyTaBlE")
require.Equal(t, ToGoIdentifier("my_table"), "MyTable") require.Equal(t, ToGoIdentifier("my_table"), "MyTable")
require.Equal(t, ToGoIdentifier("my_____table"), "MyTable")
require.Equal(t, ToGoIdentifier("MY_TABLE"), "MyTable") require.Equal(t, ToGoIdentifier("MY_TABLE"), "MyTable")
require.Equal(t, ToGoIdentifier("My_Table"), "MyTable") require.Equal(t, ToGoIdentifier("My_Table"), "MyTable")
require.Equal(t, ToGoIdentifier("My Table"), "MyTable") require.Equal(t, ToGoIdentifier("My Table"), "MyTable")
require.Equal(t, ToGoIdentifier("My-Table"), "MyTable") require.Equal(t, ToGoIdentifier("My-Table"), "MyTable")
require.Equal(t, ToGoIdentifier("EN\bUM"), "Enum") // control character
require.Equal(t, ToGoIdentifier("EN\tUM"), "EnUm") // space character
require.Equal(t, ToGoIdentifier("S3:INIT"), "S3ColonInit") // replacement chars
require.Equal(t, ToGoIdentifier("Entity-"), "Entity")
require.Equal(t, ToGoIdentifier("Entity+"), "EntityPlus")
require.Equal(t, ToGoIdentifier("="), "Equal")
require.Equal(t, ToGoIdentifier("<="), "LessEqual")
require.Equal(t, ToGoIdentifier(">="), "GreaterEqual")
require.Equal(t, ToGoIdentifier("some#$%name"), "SomeNumberDollarPercentName")
require.Equal(t, ToGoIdentifier(`An!"them`), "AnExclamationQuotationThem")
require.Equal(t, ToGoIdentifier(`An(Um)`),
"AnOpeningParenthesesUmClosingParentheses")
}
func TestNeedsCharReplacement(t *testing.T) {
increase, needs := needsCharReplacement("some_name")
require.False(t, needs)
require.Zero(t, increase)
increase, needs = needsCharReplacement("some name")
require.True(t, needs)
require.Zero(t, increase)
increase, needs = needsCharReplacement("some\bname")
require.True(t, needs)
require.Equal(t, increase, -1)
increase, needs = needsCharReplacement("some#$%name")
require.True(t, needs)
require.Equal(t, increase, 22)
}
func TestToGoFileName(t *testing.T) {
require.Equal(t, ToGoFileName("FileName"), "filename")
require.Equal(t, ToGoFileName("File_Name"), "file_name")
require.Equal(t, ToGoFileName("File___Name__"), "file___name__")
require.Equal(t, ToGoFileName("File___Name__"), "file___name__")
require.Equal(t, ToGoFileName("File\bName"), "filename")
require.Equal(t, ToGoFileName("File\tName"), "file_name")
require.Equal(t, ToGoFileName("File^^Name"), "file_caret__caret_name")
} }