Skip to content

Commit

Permalink
Replace invalid character from the go identifiers with description st…
Browse files Browse the repository at this point in the history
…ring.
  • Loading branch information
go-jet committed Feb 17, 2024
1 parent 255f4a8 commit 6b098b8
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 7 deletions.
6 changes: 4 additions & 2 deletions generator/template/sql_builder_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,13 @@ type ViewSQLBuilder = TableSQLBuilder

// DefaultTableSQLBuilder returns default implementation for TableSQLBuilder
func DefaultTableSQLBuilder(tableMetaData metadata.Table) TableSQLBuilder {
tableNameGoIdentifier := dbidentifier.ToGoIdentifier(tableMetaData.Name)

return TableSQLBuilder{
Path: "/table",
FileName: dbidentifier.ToGoFileName(tableMetaData.Name),
InstanceName: dbidentifier.ToGoIdentifier(tableMetaData.Name),
TypeName: dbidentifier.ToGoIdentifier(tableMetaData.Name) + "Table",
InstanceName: tableNameGoIdentifier,
TypeName: tableNameGoIdentifier + "Table",
DefaultAlias: "",
Column: DefaultTableSQLBuilderColumn,
}
Expand Down
93 changes: 88 additions & 5 deletions internal/utils/dbidentifier/dbidentifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package dbidentifier
import (
"github.com/go-jet/jet/v2/internal/3rdparty/snaker"
"strings"
"unicode"
)

// ToGoIdentifier converts database identifier to Go identifier.
Expand All @@ -15,10 +16,92 @@ func ToGoFileName(databaseIdentifier string) string {
return strings.ToLower(replaceInvalidChars(databaseIdentifier))
}

func replaceInvalidChars(str string) string {
str = strings.Replace(str, " ", "_", -1)
str = strings.Replace(str, "-", "_", -1)
str = strings.Replace(str, ".", "_", -1)
func replaceInvalidChars(identifier string) string {
increase, needs := needsCharReplacement(identifier)

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",
}
43 changes: 43 additions & 0 deletions internal/utils/dbidentifier/dbidentifier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
func TestToGoIdentifier(t *testing.T) {
require.Equal(t, ToGoIdentifier(""), "")
require.Equal(t, ToGoIdentifier("uuid"), "UUID")
require.Equal(t, ToGoIdentifier("uuid_ptr"), "UUIDPtr")
require.Equal(t, ToGoIdentifier("col1"), "Col1")
require.Equal(t, ToGoIdentifier("PG-13"), "Pg13")
require.Equal(t, ToGoIdentifier("13_pg"), "13Pg")
Expand All @@ -18,8 +19,50 @@ func TestToGoIdentifier(t *testing.T) {
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("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")
}

0 comments on commit 6b098b8

Please sign in to comment.