diff --git a/dialects/filter.go b/dialects/filter.go index 15044e1f..4795edb7 100644 --- a/dialects/filter.go +++ b/dialects/filter.go @@ -22,7 +22,24 @@ type QuoteFilter struct { func (s *QuoteFilter) Do(sql string, dialect Dialect, table *schemas.Table) string { quoter := dialect.Quoter() - return quoter.Quote(sql) + if quoter.IsEmpty() { + return sql + } + + prefix, suffix := quoter[0][0], quoter[1][0] + raw := []byte(sql) + for i, cnt := 0, 0; i < len(raw); i = i + 1 { + if raw[i] == '`' { + if cnt%2 == 0 { + raw[i] = prefix + } else { + raw[i] = suffix + } + cnt++ + } + } + return string(raw) + } // SeqFilter filter SQL replace ?, ? ... to $1, $2 ... diff --git a/engine.go b/engine.go index e505ac1f..b60234e0 100644 --- a/engine.go +++ b/engine.go @@ -193,10 +193,7 @@ func (engine *Engine) SupportInsertMany() bool { func (engine *Engine) quoteColumns(columnStr string) string { columns := strings.Split(columnStr, ",") - for i := 0; i < len(columns); i++ { - columns[i] = engine.Quote(strings.TrimSpace(columns[i])) - } - return strings.Join(columns, ",") + return engine.dialect.Quoter().Join(columns, ",") } // Quote Use QuoteStr quote the string sql diff --git a/schemas/quote.go b/schemas/quote.go index 5230cec8..e3571e34 100644 --- a/schemas/quote.go +++ b/schemas/quote.go @@ -5,6 +5,7 @@ package schemas import ( + "fmt" "strings" ) @@ -24,6 +25,37 @@ func (q Quoter) Quote(s string) string { return buf.String() } +func (q Quoter) Replace(sql string, newQuoter Quoter) string { + if q.IsEmpty() { + return sql + } + + if newQuoter.IsEmpty() { + var buf strings.Builder + for i := 0; i < len(sql); i = i + 1 { + if sql[i] != q[0][0] && sql[i] != q[1][0] { + _ = buf.WriteByte(sql[i]) + } + } + return buf.String() + } + + prefix, suffix := newQuoter[0][0], newQuoter[1][0] + var buf strings.Builder + for i, cnt := 0, 0; i < len(sql); i = i + 1 { + if cnt == 0 && sql[i] == q[0][0] { + _ = buf.WriteByte(prefix) + cnt = 1 + } else if cnt == 1 && sql[i] == q[1][0] { + _ = buf.WriteByte(suffix) + cnt = 0 + } else { + _ = buf.WriteByte(sql[i]) + } + } + return buf.String() +} + func (q Quoter) ReverseQuote(s string) string { reverseQuoter := Quoter{q[1], q[0]} return reverseQuoter.Quote(s) @@ -44,8 +76,31 @@ func (q Quoter) Trim(s string) string { return s } +func TrimSpaceJoin(a []string, sep string) string { + switch len(a) { + case 0: + return "" + case 1: + return a[0] + } + n := len(sep) * (len(a) - 1) + for i := 0; i < len(a); i++ { + n += len(a[i]) + } + + var b strings.Builder + b.Grow(n) + b.WriteString(strings.TrimSpace(a[0])) + for _, s := range a[1:] { + b.WriteString(sep) + b.WriteString(strings.TrimSpace(s)) + } + return b.String() +} + func (q Quoter) Join(s []string, splitter string) string { - return q.Quote(strings.Join(s, q.ReverseQuote(splitter))) + //return fmt.Sprintf("%s%s%s", q[0], TrimSpaceJoin(s, fmt.Sprintf("%s%s%s", q[1], splitter, q[0])), q[1]) + return q.Quote(TrimSpaceJoin(s, fmt.Sprintf("%s%s%s", q[1], splitter, q[0]))) } func (q Quoter) QuoteTo(buf *strings.Builder, value string) { diff --git a/schemas/quote_test.go b/schemas/quote_test.go index f89c6258..af773c8b 100644 --- a/schemas/quote_test.go +++ b/schemas/quote_test.go @@ -38,6 +38,8 @@ func TestQuoteTo(t *testing.T) { test(t, "[message_user] AS [sender]", "`message_user` AS `sender`") + assert.EqualValues(t, "[a],[b]", quoter.Join([]string{"a", " b"}, ",")) + buf := &strings.Builder{} quoter = Quoter{"", ""} quoter.QuoteTo(buf, "noquote")