Skip to content

Commit 29b162a

Browse files
Guillermo Prandilunny
authored andcommitted
Rewrite Engine.QuoteTo() to accept multi-part identifiers (#1476)
1 parent 1735906 commit 29b162a

File tree

2 files changed

+74
-12
lines changed

2 files changed

+74
-12
lines changed

engine.go

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -207,25 +207,46 @@ func (engine *Engine) QuoteTo(buf *strings.Builder, value string) {
207207
return
208208
}
209209

210-
quotePair := engine.dialect.Quote("")
210+
quoteTo(buf, engine.dialect.Quote(""), value)
211+
}
211212

212-
if value[0] == '`' || len(quotePair) < 2 || value[0] == quotePair[0] { // no quote
213+
func quoteTo(buf *strings.Builder, quotePair string, value string) {
214+
if len(quotePair) < 2 { // no quote
213215
_, _ = buf.WriteString(value)
214216
return
215-
} else {
216-
prefix, suffix := quotePair[0], quotePair[1]
217-
218-
_ = buf.WriteByte(prefix)
219-
for i := 0; i < len(value); i++ {
220-
if value[i] == '.' {
221-
_ = buf.WriteByte(suffix)
222-
_ = buf.WriteByte('.')
223-
_ = buf.WriteByte(prefix)
217+
}
218+
219+
prefix, suffix := quotePair[0], quotePair[1]
220+
221+
i := 0
222+
for i < len(value) {
223+
// start of a token; might be already quoted
224+
if value[i] == '.' {
225+
_ = buf.WriteByte('.')
226+
i++
227+
} else if value[i] == prefix || value[i] == '`' {
228+
// Has quotes; skip/normalize `name` to prefix+name+sufix
229+
var ch byte
230+
if value[i] == prefix {
231+
ch = suffix
224232
} else {
233+
ch = '`'
234+
}
235+
i++
236+
_ = buf.WriteByte(prefix)
237+
for ; i < len(value) && value[i] != ch; i++ {
238+
_ = buf.WriteByte(value[i])
239+
}
240+
_ = buf.WriteByte(suffix)
241+
i++
242+
} else {
243+
// Requires quotes
244+
_ = buf.WriteByte(prefix)
245+
for ; i < len(value) && value[i] != '.'; i++ {
225246
_ = buf.WriteByte(value[i])
226247
}
248+
_ = buf.WriteByte(suffix)
227249
}
228-
_ = buf.WriteByte(suffix)
229250
}
230251
}
231252

engine_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright 2019 The Xorm Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package xorm
6+
7+
import (
8+
"strings"
9+
"testing"
10+
11+
"github.com/stretchr/testify/assert"
12+
)
13+
14+
func TestQuoteTo(t *testing.T) {
15+
16+
test := func(t *testing.T, expected string, value string) {
17+
buf := &strings.Builder{}
18+
quoteTo(buf, "[]", value)
19+
assert.EqualValues(t, expected, buf.String())
20+
}
21+
22+
test(t, "[mytable]", "mytable")
23+
test(t, "[mytable]", "`mytable`")
24+
test(t, "[mytable]", `[mytable]`)
25+
26+
test(t, `["mytable"]`, `"mytable"`)
27+
28+
test(t, "[myschema].[mytable]", "myschema.mytable")
29+
test(t, "[myschema].[mytable]", "`myschema`.mytable")
30+
test(t, "[myschema].[mytable]", "myschema.`mytable`")
31+
test(t, "[myschema].[mytable]", "`myschema`.`mytable`")
32+
test(t, "[myschema].[mytable]", `[myschema].mytable`)
33+
test(t, "[myschema].[mytable]", `myschema.[mytable]`)
34+
test(t, "[myschema].[mytable]", `[myschema].[mytable]`)
35+
36+
test(t, `["myschema].[mytable"]`, `"myschema.mytable"`)
37+
38+
buf := &strings.Builder{}
39+
quoteTo(buf, "", "noquote")
40+
assert.EqualValues(t, "noquote", buf.String())
41+
}

0 commit comments

Comments
 (0)