xorm/schemas/quote.go

111 lines
2.3 KiB
Go
Raw Normal View History

2020-02-24 13:36:09 +00:00
// Copyright 2020 The Xorm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package schemas
import (
"strings"
)
// Quoter represents two quote characters
type Quoter [2]string
// CommonQuoter represetns a common quoter
var CommonQuoter = Quoter{"`", "`"}
func (q Quoter) IsEmpty() bool {
return q[0] == "" && q[1] == ""
}
func (q Quoter) Quote(s string) string {
var buf strings.Builder
q.QuoteTo(&buf, s)
return buf.String()
}
func (q Quoter) ReverseQuote(s string) string {
reverseQuoter := Quoter{q[1], q[0]}
return reverseQuoter.Quote(s)
}
// Trim removes quotes from s
func (q Quoter) Trim(s string) string {
if len(s) < 2 {
return s
}
if s[0:1] == q[0] {
s = s[1:]
}
if len(s) > 0 && s[len(s)-1:] == q[0] {
return s[:len(s)-1]
}
return s
}
func (q Quoter) Join(s []string, splitter string) string {
return q.Quote(strings.Join(s, q.ReverseQuote(splitter)))
}
func (q Quoter) QuoteTo(buf *strings.Builder, value string) {
if q.IsEmpty() {
buf.WriteString(value)
return
}
prefix, suffix := q[0][0], q[1][0]
lastCh := 0 // 0 prefix, 1 char, 2 suffix
i := 0
for i < len(value) {
// start of a token; might be already quoted
if value[i] == '.' {
_ = buf.WriteByte('.')
lastCh = 1
i++
} else if value[i] == prefix || value[i] == '`' {
// Has quotes; skip/normalize `name` to prefix+name+sufix
var ch byte
if value[i] == prefix {
ch = suffix
} else {
ch = '`'
}
_ = buf.WriteByte(prefix)
i++
lastCh = 0
for ; i < len(value) && value[i] != ch && value[i] != ' '; i++ {
_ = buf.WriteByte(value[i])
lastCh = 1
}
_ = buf.WriteByte(suffix)
lastCh = 2
i++
} else if value[i] == ' ' {
if lastCh != 2 {
_ = buf.WriteByte(suffix)
lastCh = 2
}
// a AS b or a b
for ; i < len(value); i++ {
if value[i] != ' ' && value[i-1] == ' ' && (len(value) > i+1 && !strings.EqualFold(value[i:i+2], "AS")) {
break
}
_ = buf.WriteByte(value[i])
lastCh = 1
}
} else {
// Requires quotes
_ = buf.WriteByte(prefix)
for ; i < len(value) && value[i] != '.' && value[i] != ' '; i++ {
_ = buf.WriteByte(value[i])
lastCh = 1
}
_ = buf.WriteByte(suffix)
lastCh = 2
}
}
}