[bug] Escape reserved words used as identifier.

This commit is contained in:
go-jet 2020-02-16 10:25:21 +01:00
parent 63c1fd6430
commit 3019fdbbb2
10 changed files with 226 additions and 4 deletions

View file

@ -1,5 +1,7 @@
package jet
import "strings"
// Dialect interface
type Dialect interface {
Name() string
@ -9,6 +11,7 @@ type Dialect interface {
AliasQuoteChar() byte
IdentifierQuoteChar() byte
ArgumentPlaceholder() QueryPlaceholderFunc
IsReservedWord(name string) bool
}
// SerializerFunc func
@ -29,6 +32,7 @@ type DialectParams struct {
AliasQuoteChar byte
IdentifierQuoteChar byte
ArgumentPlaceholder QueryPlaceholderFunc
ReservedWords []string
}
// NewDialect creates new dialect with params
@ -41,6 +45,7 @@ func NewDialect(params DialectParams) Dialect {
aliasQuoteChar: params.AliasQuoteChar,
identifierQuoteChar: params.IdentifierQuoteChar,
argumentPlaceholder: params.ArgumentPlaceholder,
reservedWords: arrayOfStringsToMapOfStrings(params.ReservedWords),
}
}
@ -52,6 +57,7 @@ type dialectImpl struct {
aliasQuoteChar byte
identifierQuoteChar byte
argumentPlaceholder QueryPlaceholderFunc
reservedWords map[string]bool
supportsReturning bool
}
@ -89,3 +95,17 @@ func (d *dialectImpl) IdentifierQuoteChar() byte {
func (d *dialectImpl) ArgumentPlaceholder() QueryPlaceholderFunc {
return d.argumentPlaceholder
}
func (d *dialectImpl) IsReservedWord(name string) bool {
_, isReservedWord := d.reservedWords[strings.ToLower(name)]
return isReservedWord
}
func arrayOfStringsToMapOfStrings(arr []string) map[string]bool {
ret := map[string]bool{}
for _, elem := range arr {
ret[strings.ToLower(elem)] = true
}
return ret
}

View file

@ -98,7 +98,7 @@ func (s *SQLBuilder) WriteString(str string) {
// WriteIdentifier adds identifier to output SQL
func (s *SQLBuilder) WriteIdentifier(name string, alwaysQuote ...bool) {
if shouldQuoteIdentifier(name) || len(alwaysQuote) > 0 {
if s.Dialect.IsReservedWord(name) || shouldQuoteIdentifier(name) || len(alwaysQuote) > 0 {
identQuoteChar := string(s.Dialect.IdentifierQuoteChar())
s.WriteString(identQuoteChar + name + identQuoteChar)
} else {

View file

@ -211,6 +211,7 @@ func AssertFileNamesEqual(t *testing.T, fileInfos []os.FileInfo, fileNames ...st
}
}
// AssertDeepEqual checks if actual and expected objects are deeply equal.
func AssertDeepEqual(t *testing.T, actual, expected interface{}) {
assert.True(t, cmp.Equal(actual, expected))
}

View file

@ -18,6 +18,7 @@ func ToGoIdentifier(databaseIdentifier string) string {
return snaker.SnakeToCamel(replaceInvalidChars(databaseIdentifier))
}
// ToGoEnumValueIdentifier converts enum value name to Go identifier name.
func ToGoEnumValueIdentifier(enumName, enumValue string) string {
enumValueIdentifier := ToGoIdentifier(enumValue)
if !unicode.IsLetter([]rune(enumValueIdentifier)[0]) {