Rewrite Engine.QuoteTo() to accept multi-part identifiers #1476

Merged
lunny merged 7 commits from :fix-quotes-schema into master 2019-11-12 00:48:24 +00:00
2 changed files with 73 additions and 11 deletions

View File

@ -207,25 +207,46 @@ func (engine *Engine) QuoteTo(buf *strings.Builder, value string) {
return
}
quotePair := engine.dialect.Quote("")
quoteTo(buf, engine.dialect.Quote(""), value)
}
if value[0] == '`' || len(quotePair) < 2 || value[0] == quotePair[0] { // no quote
func quoteTo(buf *strings.Builder, quotePair string, value string) {
if len(quotePair) < 2 { // no quote
_, _ = buf.WriteString(value)
return
} else {
prefix, suffix := quotePair[0], quotePair[1]
}
Outdated
Review

else is unnecessary.

`else` is unnecessary.
Review

else is unnecessary.

Indeed. Fixed.

> else is unnecessary. Indeed. Fixed.
prefix, suffix := quotePair[0], quotePair[1]
_ = buf.WriteByte(prefix)
for i := 0; i < len(value); i++ {
if value[i] == '.' {
_ = buf.WriteByte(suffix)
_ = buf.WriteByte('.')
_ = buf.WriteByte(prefix)
i := 0
for i < len(value) {
// start of a token; might be already quoted
if value[i] == '.' {
_ = buf.WriteByte('.')
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 = '`'
}
i++
_ = buf.WriteByte(prefix)
for ; i < len(value) && value[i] != ch; i++ {
_ = buf.WriteByte(value[i])
}
_ = buf.WriteByte(suffix)
i++
} else {
// Requires quotes
_ = buf.WriteByte(prefix)
for ; i < len(value) && value[i] != '.'; i++ {
_ = buf.WriteByte(value[i])
}
_ = buf.WriteByte(suffix)
}
_ = buf.WriteByte(suffix)
}
}

41
engine_test.go Normal file
View File

@ -0,0 +1,41 @@
// Copyright 2019 The Xorm Authors. All rights reserved.
Outdated
Review

2019

2019
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package xorm
import (
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
func TestQuoteTo(t *testing.T) {
test := func(t *testing.T, expected string, value string) {
buf := &strings.Builder{}
quoteTo(buf, "[]", value)
assert.EqualValues(t, expected, buf.String())
}
test(t, "[mytable]", "mytable")
test(t, "[mytable]", "`mytable`")
test(t, "[mytable]", `[mytable]`)
test(t, `["mytable"]`, `"mytable"`)
test(t, "[myschema].[mytable]", "myschema.mytable")
test(t, "[myschema].[mytable]", "`myschema`.mytable")
test(t, "[myschema].[mytable]", "myschema.`mytable`")
test(t, "[myschema].[mytable]", "`myschema`.`mytable`")
test(t, "[myschema].[mytable]", `[myschema].mytable`)
test(t, "[myschema].[mytable]", `myschema.[mytable]`)
test(t, "[myschema].[mytable]", `[myschema].[mytable]`)
test(t, `["myschema].[mytable"]`, `"myschema.mytable"`)
buf := &strings.Builder{}
quoteTo(buf, "", "noquote")
assert.EqualValues(t, "noquote", buf.String())
}