Fix label count (#8267)

* fix label count

* fix vendor

* fix import order

* update xorm to fix bug

* fix tests

* fix mssql bug
This commit is contained in:
Lunny Xiao 2019-09-24 21:22:39 +08:00 committed by GitHub
parent 7cccada51e
commit 29dda47cbb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
38 changed files with 959 additions and 580 deletions

115
vendor/xorm.io/builder/.drone.yml generated vendored
View file

@ -1,37 +1,90 @@
---
kind: pipeline
name: go1.10
workspace:
base: /go
path: src/github.com/go-xorm/builder
path: src/xorm.io/builder
clone:
git:
image: plugins/git:next
depth: 50
tags: true
steps:
- name: test
pull: default
image: golang:1.10
commands:
- go get -u golang.org/x/lint/golint
- go get -u github.com/stretchr/testify/assert
- go get -u github.com/go-xorm/sqlfiddle
- golint ./...
- go vet
- go test -v -race -coverprofile=coverage.txt -covermode=atomic
when:
event:
- push
- tag
- pull_request
matrix:
GO_VERSION:
- 1.8
- 1.9
- 1.10
- 1.11
---
kind: pipeline
name: go1.11
pipeline:
test:
image: golang:${GO_VERSION}
commands:
- go get -u github.com/golang/lint/golint
- go get -u github.com/stretchr/testify/assert
- go get -u github.com/go-xorm/sqlfiddle
- golint ./...
- go test -v -race -coverprofile=coverage.txt -covermode=atomic
when:
event: [ push, tag, pull_request ]
steps:
- name: test
pull: default
image: golang:1.11
commands:
- go get -u golang.org/x/lint/golint
- golint ./...
- go vet
- go test -v -race -coverprofile=coverage.txt -covermode=atomic
environment:
GOPROXY: https://goproxy.cn
GO111MODULE: "on"
when:
event:
- push
- tag
- pull_request
codecov:
image: robertstettner/drone-codecov
group: build
secrets: [ codecov_token ]
files:
- coverage.txt
when:
event: [ push, pull_request ]
---
kind: pipeline
name: go1.12
steps:
- name: test
pull: default
image: golang:1.12
commands:
- go get -u golang.org/x/lint/golint
- golint ./...
- go vet
- go test -v -race -coverprofile=coverage.txt -covermode=atomic
environment:
GOPROXY: https://goproxy.cn
GO111MODULE: "on"
when:
event:
- push
- tag
- pull_request
---
kind: pipeline
name: go1.13
steps:
- name: test
pull: default
image: golang:1.13
commands:
- go get -u golang.org/x/lint/golint
- golint ./...
- go vet
- go test -v -race -coverprofile=coverage.txt -covermode=atomic
environment:
GOPROXY: https://goproxy.cn
GO111MODULE: "on"
when:
event:
- push
- tag
- pull_request

26
vendor/xorm.io/builder/README.md generated vendored
View file

@ -1,13 +1,13 @@
# SQL builder
[![GitCI.cn](https://gitci.cn/api/badges/go-xorm/builder/status.svg)](https://gitci.cn/go-xorm/builder) [![codecov](https://codecov.io/gh/go-xorm/builder/branch/master/graph/badge.svg)](https://codecov.io/gh/go-xorm/builder)
[![](https://goreportcard.com/badge/github.com/go-xorm/builder)](https://goreportcard.com/report/github.com/go-xorm/builder)
[![Build Status](https://drone.gitea.com/api/badges/xorm/builder/status.svg)](https://drone.gitea.com/xorm/builder) [![](http://gocover.io/_badge/xorm.io/builder)](http://gocover.io/xorm.io/builder)
[![](https://goreportcard.com/badge/xorm.io/builder)](https://goreportcard.com/report/xorm.io/builder)
Package builder is a lightweight and fast SQL builder for Go and XORM.
Make sure you have installed Go 1.8+ and then:
go get github.com/go-xorm/builder
go get xorm.io/builder
# Insert
@ -71,7 +71,7 @@ sql, args, err := Select("*").From("a").Where(Eq{"status": "1"}).
* `Eq` is a redefine of a map, you can give one or more conditions to `Eq`
```Go
import . "github.com/go-xorm/builder"
import . "xorm.io/builder"
sql, args, _ := ToSQL(Eq{"a":1})
// a=? [1]
@ -90,7 +90,7 @@ sql, args, _ := ToSQL(Eq{"b": 1, "c":[]int{2, 3}})
* `Neq` is the same to `Eq`
```Go
import . "github.com/go-xorm/builder"
import . "xorm.io/builder"
sql, args, _ := ToSQL(Neq{"a":1})
// a<>? [1]
@ -109,7 +109,7 @@ sql, args, _ := ToSQL(Neq{"b": 1, "c":[]int{2, 3}})
* `Gt`, `Gte`, `Lt`, `Lte`
```Go
import . "github.com/go-xorm/builder"
import . "xorm.io/builder"
sql, args, _ := ToSQL(Gt{"a", 1}.And(Gte{"b", 2}))
// a>? AND b>=? [1, 2]
@ -120,7 +120,7 @@ sql, args, _ := ToSQL(Lt{"a", 1}.Or(Lte{"b", 2}))
* `Like`
```Go
import . "github.com/go-xorm/builder"
import . "xorm.io/builder"
sql, args, _ := ToSQL(Like{"a", "c"})
// a LIKE ? [%c%]
@ -129,7 +129,7 @@ sql, args, _ := ToSQL(Like{"a", "c"})
* `Expr` you can customerize your sql with `Expr`
```Go
import . "github.com/go-xorm/builder"
import . "xorm.io/builder"
sql, args, _ := ToSQL(Expr("a = ? ", 1))
// a = ? [1]
@ -140,7 +140,7 @@ sql, args, _ := ToSQL(Eq{"a": Expr("select id from table where c = ?", 1)})
* `In` and `NotIn`
```Go
import . "github.com/go-xorm/builder"
import . "xorm.io/builder"
sql, args, _ := ToSQL(In("a", 1, 2, 3))
// a IN (?,?,?) [1,2,3]
@ -153,7 +153,7 @@ sql, args, _ := ToSQL(In("a", Expr("select id from b where c = ?", 1))))
* `IsNull` and `NotNull`
```Go
import . "github.com/go-xorm/builder"
import . "xorm.io/builder"
sql, args, _ := ToSQL(IsNull{"a"})
// a IS NULL []
@ -164,7 +164,7 @@ sql, args, _ := ToSQL(NotNull{"b"})
* `And(conds ...Cond)`, And can connect one or more condtions via And
```Go
import . "github.com/go-xorm/builder"
import . "xorm.io/builder"
sql, args, _ := ToSQL(And(Eq{"a":1}, Like{"b", "c"}, Neq{"d", 2}))
// a=? AND b LIKE ? AND d<>? [1, %c%, 2]
@ -173,7 +173,7 @@ sql, args, _ := ToSQL(And(Eq{"a":1}, Like{"b", "c"}, Neq{"d", 2}))
* `Or(conds ...Cond)`, Or can connect one or more conditions via Or
```Go
import . "github.com/go-xorm/builder"
import . "xorm.io/builder"
sql, args, _ := ToSQL(Or(Eq{"a":1}, Like{"b", "c"}, Neq{"d", 2}))
// a=? OR b LIKE ? OR d<>? [1, %c%, 2]
@ -184,7 +184,7 @@ sql, args, _ := ToSQL(Or(Eq{"a":1}, And(Like{"b", "c"}, Neq{"d", 2})))
* `Between`
```Go
import . "github.com/go-xorm/builder"
import . "xorm.io/builder"
sql, args, _ := ToSQL(Between{"a", 1, 2})
// a BETWEEN 1 AND 2

113
vendor/xorm.io/builder/builder.go generated vendored
View file

@ -7,7 +7,6 @@ package builder
import (
sql2 "database/sql"
"fmt"
"sort"
)
type optype byte
@ -21,6 +20,7 @@ const (
unionType // union
)
// all databasees
const (
POSTGRES = "postgres"
SQLITE = "sqlite3"
@ -31,7 +31,7 @@ const (
type join struct {
joinType string
joinTable string
joinTable interface{}
joinCond Cond
}
@ -60,7 +60,7 @@ type Builder struct {
limitation *limit
insertCols []string
insertVals []interface{}
updates []Eq
updates []UpdateCond
orderBy string
groupBy string
having string
@ -143,18 +143,6 @@ func (b *Builder) Into(tableName string) *Builder {
return b
}
// Join sets join table and conditions
func (b *Builder) Join(joinType, joinTable string, joinCond interface{}) *Builder {
switch joinCond.(type) {
case Cond:
b.joins = append(b.joins, join{joinType, joinTable, joinCond.(Cond)})
case string:
b.joins = append(b.joins, join{joinType, joinTable, Expr(joinCond.(string))})
}
return b
}
// Union sets union conditions
func (b *Builder) Union(unionTp string, unionCond *Builder) *Builder {
var builder *Builder
@ -199,31 +187,6 @@ func (b *Builder) Limit(limitN int, offset ...int) *Builder {
return b
}
// InnerJoin sets inner join
func (b *Builder) InnerJoin(joinTable string, joinCond interface{}) *Builder {
return b.Join("INNER", joinTable, joinCond)
}
// LeftJoin sets left join SQL
func (b *Builder) LeftJoin(joinTable string, joinCond interface{}) *Builder {
return b.Join("LEFT", joinTable, joinCond)
}
// RightJoin sets right join SQL
func (b *Builder) RightJoin(joinTable string, joinCond interface{}) *Builder {
return b.Join("RIGHT", joinTable, joinCond)
}
// CrossJoin sets cross join SQL
func (b *Builder) CrossJoin(joinTable string, joinCond interface{}) *Builder {
return b.Join("CROSS", joinTable, joinCond)
}
// FullJoin sets full join SQL
func (b *Builder) FullJoin(joinTable string, joinCond interface{}) *Builder {
return b.Join("FULL", joinTable, joinCond)
}
// Select sets select SQL
func (b *Builder) Select(cols ...string) *Builder {
b.selects = cols
@ -245,68 +208,12 @@ func (b *Builder) Or(cond Cond) *Builder {
return b
}
type insertColsSorter struct {
cols []string
vals []interface{}
}
func (s insertColsSorter) Len() int {
return len(s.cols)
}
func (s insertColsSorter) Swap(i, j int) {
s.cols[i], s.cols[j] = s.cols[j], s.cols[i]
s.vals[i], s.vals[j] = s.vals[j], s.vals[i]
}
func (s insertColsSorter) Less(i, j int) bool {
return s.cols[i] < s.cols[j]
}
// Insert sets insert SQL
func (b *Builder) Insert(eq ...interface{}) *Builder {
if len(eq) > 0 {
var paramType = -1
for _, e := range eq {
switch t := e.(type) {
case Eq:
if paramType == -1 {
paramType = 0
}
if paramType != 0 {
break
}
for k, v := range t {
b.insertCols = append(b.insertCols, k)
b.insertVals = append(b.insertVals, v)
}
case string:
if paramType == -1 {
paramType = 1
}
if paramType != 1 {
break
}
b.insertCols = append(b.insertCols, t)
}
}
}
if len(b.insertCols) == len(b.insertVals) {
sort.Sort(insertColsSorter{
cols: b.insertCols,
vals: b.insertVals,
})
}
b.optype = insertType
return b
}
// Update sets update SQL
func (b *Builder) Update(updates ...Eq) *Builder {
b.updates = make([]Eq, 0, len(updates))
func (b *Builder) Update(updates ...Cond) *Builder {
b.updates = make([]UpdateCond, 0, len(updates))
for _, update := range updates {
if update.IsValid() {
b.updates = append(b.updates, update)
if u, ok := update.(UpdateCond); ok && u.IsValid() {
b.updates = append(b.updates, u)
}
}
b.optype = updateType
@ -354,7 +261,7 @@ func (b *Builder) ToSQL() (string, []interface{}, error) {
}
}
var sql = w.writer.String()
var sql = w.String()
var err error
switch b.dialect {
@ -383,12 +290,12 @@ func (b *Builder) ToSQL() (string, []interface{}, error) {
return sql, w.args, nil
}
// ToBoundSQL
// ToBoundSQL generated a bound SQL string
func (b *Builder) ToBoundSQL() (string, error) {
w := NewWriter()
if err := b.WriteTo(w); err != nil {
return "", err
}
return ConvertToBoundSQL(w.writer.String(), w.args)
return ConvertToBoundSQL(w.String(), w.args)
}

View file

@ -7,6 +7,7 @@ package builder
import (
"bytes"
"fmt"
"sort"
)
// Insert creates an insert Builder
@ -87,3 +88,60 @@ func (b *Builder) insertWriteTo(w Writer) error {
return nil
}
type insertColsSorter struct {
cols []string
vals []interface{}
}
func (s insertColsSorter) Len() int {
return len(s.cols)
}
func (s insertColsSorter) Swap(i, j int) {
s.cols[i], s.cols[j] = s.cols[j], s.cols[i]
s.vals[i], s.vals[j] = s.vals[j], s.vals[i]
}
func (s insertColsSorter) Less(i, j int) bool {
return s.cols[i] < s.cols[j]
}
// Insert sets insert SQL
func (b *Builder) Insert(eq ...interface{}) *Builder {
if len(eq) > 0 {
var paramType = -1
for _, e := range eq {
switch t := e.(type) {
case Eq:
if paramType == -1 {
paramType = 0
}
if paramType != 0 {
break
}
for k, v := range t {
b.insertCols = append(b.insertCols, k)
b.insertVals = append(b.insertVals, v)
}
case string:
if paramType == -1 {
paramType = 1
}
if paramType != 1 {
break
}
b.insertCols = append(b.insertCols, t)
}
}
}
if len(b.insertCols) == len(b.insertVals) {
sort.Sort(insertColsSorter{
cols: b.insertCols,
vals: b.insertVals,
})
}
b.optype = insertType
return b
}

42
vendor/xorm.io/builder/builder_join.go generated vendored Normal file
View file

@ -0,0 +1,42 @@
// Copyright 2019 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 builder
// InnerJoin sets inner join
func (b *Builder) InnerJoin(joinTable, joinCond interface{}) *Builder {
return b.Join("INNER", joinTable, joinCond)
}
// LeftJoin sets left join SQL
func (b *Builder) LeftJoin(joinTable, joinCond interface{}) *Builder {
return b.Join("LEFT", joinTable, joinCond)
}
// RightJoin sets right join SQL
func (b *Builder) RightJoin(joinTable, joinCond interface{}) *Builder {
return b.Join("RIGHT", joinTable, joinCond)
}
// CrossJoin sets cross join SQL
func (b *Builder) CrossJoin(joinTable, joinCond interface{}) *Builder {
return b.Join("CROSS", joinTable, joinCond)
}
// FullJoin sets full join SQL
func (b *Builder) FullJoin(joinTable, joinCond interface{}) *Builder {
return b.Join("FULL", joinTable, joinCond)
}
// Join sets join table and conditions
func (b *Builder) Join(joinType string, joinTable, joinCond interface{}) *Builder {
switch joinCond.(type) {
case Cond:
b.joins = append(b.joins, join{joinType, joinTable, joinCond.(Cond)})
case string:
b.joins = append(b.joins, join{joinType, joinTable, Expr(joinCond.(string))})
}
return b
}

View file

@ -80,8 +80,21 @@ func (b *Builder) selectWriteTo(w Writer) error {
}
for _, v := range b.joins {
if _, err := fmt.Fprintf(w, " %s JOIN %s ON ", v.joinType, v.joinTable); err != nil {
return err
b, ok := v.joinTable.(*Builder)
if ok {
if _, err := fmt.Fprintf(w, " %s JOIN (", v.joinType); err != nil {
return err
}
if err := b.WriteTo(w); err != nil {
return err
}
if _, err := fmt.Fprintf(w, ") ON "); err != nil {
return err
}
} else {
if _, err := fmt.Fprintf(w, " %s JOIN %s ON ", v.joinType, v.joinTable); err != nil {
return err
}
}
if err := v.joinCond.WriteTo(w); err != nil {

View file

@ -8,8 +8,14 @@ import (
"fmt"
)
// UpdateCond defines an interface that cond could be used with update
type UpdateCond interface {
IsValid() bool
OpWriteTo(op string, w Writer) error
}
// Update creates an update Builder
func Update(updates ...Eq) *Builder {
func Update(updates ...Cond) *Builder {
builder := &Builder{cond: NewCond()}
return builder.Update(updates...)
}
@ -27,7 +33,8 @@ func (b *Builder) updateWriteTo(w Writer) error {
}
for i, s := range b.updates {
if err := s.opWriteTo(",", w); err != nil {
if err := s.OpWriteTo(",", w); err != nil {
return err
}

36
vendor/xorm.io/builder/cond.go generated vendored
View file

@ -4,42 +4,6 @@
package builder
import (
"io"
)
// Writer defines the interface
type Writer interface {
io.Writer
Append(...interface{})
}
var _ Writer = NewWriter()
// BytesWriter implments Writer and save SQL in bytes.Buffer
type BytesWriter struct {
writer *StringBuilder
args []interface{}
}
// NewWriter creates a new string writer
func NewWriter() *BytesWriter {
w := &BytesWriter{
writer: &StringBuilder{},
}
return w
}
// Write writes data to Writer
func (s *BytesWriter) Write(buf []byte) (int, error) {
return s.writer.Write(buf)
}
// Append appends args to Writer
func (s *BytesWriter) Append(args ...interface{}) {
s.args = append(s.args, args...)
}
// Cond defines an interface
type Cond interface {
WriteTo(Writer) error

7
vendor/xorm.io/builder/cond_eq.go generated vendored
View file

@ -20,7 +20,8 @@ type Eq map[string]interface{}
var _ Cond = Eq{}
func (eq Eq) opWriteTo(op string, w Writer) error {
// OpWriteTo writes conditions with special operator
func (eq Eq) OpWriteTo(op string, w Writer) error {
var i = 0
for _, k := range eq.sortedKeys() {
v := eq[k]
@ -81,7 +82,7 @@ func (eq Eq) opWriteTo(op string, w Writer) error {
// WriteTo writes SQL to Writer
func (eq Eq) WriteTo(w Writer) error {
return eq.opWriteTo(" AND ", w)
return eq.OpWriteTo(" AND ", w)
}
// And implements And with other conditions
@ -101,7 +102,7 @@ func (eq Eq) IsValid() bool {
// sortedKeys returns all keys of this Eq sorted with sort.Strings.
// It is used internally for consistent ordering when generating
// SQL, see https://github.com/go-xorm/builder/issues/10
// SQL, see https://gitea.com/xorm/builder/issues/10
func (eq Eq) sortedKeys() []string {
keys := make([]string, 0, len(eq))
for key := range eq {

View file

@ -18,6 +18,10 @@ func Expr(sql string, args ...interface{}) Cond {
return expr{sql, args}
}
func (expr expr) OpWriteTo(op string, w Writer) error {
return expr.WriteTo(w)
}
func (expr expr) WriteTo(w Writer) error {
if _, err := fmt.Fprint(w, expr.sql); err != nil {
return err

2
vendor/xorm.io/builder/cond_neq.go generated vendored
View file

@ -83,7 +83,7 @@ func (neq Neq) IsValid() bool {
// sortedKeys returns all keys of this Neq sorted with sort.Strings.
// It is used internally for consistent ordering when generating
// SQL, see https://github.com/go-xorm/builder/issues/10
// SQL, see https://gitea.com/xorm/builder/issues/10
func (neq Neq) sortedKeys() []string {
keys := make([]string, 0, len(neq))
for key := range neq {

22
vendor/xorm.io/builder/doc.go generated vendored
View file

@ -8,13 +8,13 @@ Package builder is a simple and powerful sql builder for Go.
Make sure you have installed Go 1.1+ and then:
go get github.com/go-xorm/builder
go get xorm.io/builder
WARNNING: Currently, only query conditions are supported. Below is the supported conditions.
1. Eq is a redefine of a map, you can give one or more conditions to Eq
import . "github.com/go-xorm/builder"
import . "xorm.io/builder"
sql, args, _ := ToSQL(Eq{"a":1})
// a=? [1]
@ -31,7 +31,7 @@ WARNNING: Currently, only query conditions are supported. Below is the supported
2. Neq is the same to Eq
import . "github.com/go-xorm/builder"
import . "xorm.io/builder"
sql, args, _ := ToSQL(Neq{"a":1})
// a<>? [1]
@ -48,7 +48,7 @@ WARNNING: Currently, only query conditions are supported. Below is the supported
3. Gt, Gte, Lt, Lte
import . "github.com/go-xorm/builder"
import . "xorm.io/builder"
sql, args, _ := ToSQL(Gt{"a", 1}.And(Gte{"b", 2}))
// a>? AND b>=? [1, 2]
@ -57,14 +57,14 @@ WARNNING: Currently, only query conditions are supported. Below is the supported
4. Like
import . "github.com/go-xorm/builder"
import . "xorm.io/builder"
sql, args, _ := ToSQL(Like{"a", "c"})
// a LIKE ? [%c%]
5. Expr you can customerize your sql with Expr
import . "github.com/go-xorm/builder"
import . "xorm.io/builder"
sql, args, _ := ToSQL(Expr("a = ? ", 1))
// a = ? [1]
@ -73,7 +73,7 @@ WARNNING: Currently, only query conditions are supported. Below is the supported
6. In and NotIn
import . "github.com/go-xorm/builder"
import . "xorm.io/builder"
sql, args, _ := ToSQL(In("a", 1, 2, 3))
// a IN (?,?,?) [1,2,3]
@ -84,7 +84,7 @@ WARNNING: Currently, only query conditions are supported. Below is the supported
7. IsNull and NotNull
import . "github.com/go-xorm/builder"
import . "xorm.io/builder"
sql, args, _ := ToSQL(IsNull{"a"})
// a IS NULL []
@ -93,14 +93,14 @@ WARNNING: Currently, only query conditions are supported. Below is the supported
8. And(conds ...Cond), And can connect one or more condtions via AND
import . "github.com/go-xorm/builder"
import . "xorm.io/builder"
sql, args, _ := ToSQL(And(Eq{"a":1}, Like{"b", "c"}, Neq{"d", 2}))
// a=? AND b LIKE ? AND d<>? [1, %c%, 2]
9. Or(conds ...Cond), Or can connect one or more conditions via Or
import . "github.com/go-xorm/builder"
import . "xorm.io/builder"
sql, args, _ := ToSQL(Or(Eq{"a":1}, Like{"b", "c"}, Neq{"d", 2}))
// a=? OR b LIKE ? OR d<>? [1, %c%, 2]
@ -109,7 +109,7 @@ WARNNING: Currently, only query conditions are supported. Below is the supported
10. Between
import . "github.com/go-xorm/builder"
import . "xorm.io/builder"
sql, args, _ := ToSQL(Between("a", 1, 2))
// a BETWEEN 1 AND 2

4
vendor/xorm.io/builder/error.go generated vendored
View file

@ -17,9 +17,9 @@ var (
ErrNeedMoreArguments = errors.New("Need more sql arguments")
// ErrNoTableName no table name
ErrNoTableName = errors.New("No table indicated")
// ErrNoColumnToInsert no column to update
// ErrNoColumnToUpdate no column to update
ErrNoColumnToUpdate = errors.New("No column(s) to update")
// ErrNoColumnToInsert no column to update
// ErrNoColumnToInsert no column to insert
ErrNoColumnToInsert = errors.New("No column(s) to insert")
// ErrNotSupportDialectType not supported dialect type error
ErrNotSupportDialectType = errors.New("Not supported dialect type")

2
vendor/xorm.io/builder/go.mod generated vendored
View file

@ -1,5 +1,7 @@
module xorm.io/builder
go 1.11
require (
github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a
github.com/stretchr/testify v1.3.0

14
vendor/xorm.io/builder/sql.go generated vendored
View file

@ -8,6 +8,7 @@ import (
sql2 "database/sql"
"fmt"
"reflect"
"strings"
"time"
)
@ -20,7 +21,7 @@ func condToSQL(cond Cond) (string, []interface{}, error) {
if err := cond.WriteTo(w); err != nil {
return "", nil, err
}
return w.writer.String(), w.args, nil
return w.String(), w.args, nil
}
func condToBoundSQL(cond Cond) (string, error) {
@ -32,7 +33,7 @@ func condToBoundSQL(cond Cond) (string, error) {
if err := cond.WriteTo(w); err != nil {
return "", err
}
return ConvertToBoundSQL(w.writer.String(), w.args)
return ConvertToBoundSQL(w.String(), w.args)
}
// ToSQL convert a builder or conditions to SQL and args
@ -92,7 +93,7 @@ func noSQLQuoteNeeded(a interface{}) bool {
// ConvertToBoundSQL will convert SQL and args to a bound SQL
func ConvertToBoundSQL(sql string, args []interface{}) (string, error) {
buf := StringBuilder{}
buf := strings.Builder{}
var i, j, start int
for ; i < len(sql); i++ {
if sql[i] == '?' {
@ -114,7 +115,10 @@ func ConvertToBoundSQL(sql string, args []interface{}) (string, error) {
if noSQLQuoteNeeded(arg) {
_, err = fmt.Fprint(&buf, arg)
} else {
_, err = fmt.Fprintf(&buf, "'%v'", arg)
// replace ' -> '' (standard replacement) to avoid critical SQL injection,
// NOTICE: may allow some injection like % (or _) in LIKE query
_, err = fmt.Fprintf(&buf, "'%v'", strings.Replace(fmt.Sprintf("%v", arg), "'",
"''", -1))
}
if err != nil {
return "", err
@ -131,7 +135,7 @@ func ConvertToBoundSQL(sql string, args []interface{}) (string, error) {
// ConvertPlaceholder replaces ? to $1, $2 ... or :1, :2 ... according prefix
func ConvertPlaceholder(sql, prefix string) (string, error) {
buf := StringBuilder{}
buf := strings.Builder{}
var i, j, start int
for ; i < len(sql); i++ {
if sql[i] == '?' {

View file

@ -1,119 +0,0 @@
// Copyright 2017 The Go 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 builder
import (
"unicode/utf8"
"unsafe"
)
// A StringBuilder is used to efficiently build a string using Write methods.
// It minimizes memory copying. The zero value is ready to use.
// Do not copy a non-zero Builder.
type StringBuilder struct {
addr *StringBuilder // of receiver, to detect copies by value
buf []byte
}
// noescape hides a pointer from escape analysis. noescape is
// the identity function but escape analysis doesn't think the
// output depends on the input. noescape is inlined and currently
// compiles down to zero instructions.
// USE CAREFULLY!
// This was copied from the runtime; see issues 23382 and 7921.
//go:nosplit
func noescape(p unsafe.Pointer) unsafe.Pointer {
x := uintptr(p)
return unsafe.Pointer(x ^ 0)
}
func (b *StringBuilder) copyCheck() {
if b.addr == nil {
// This hack works around a failing of Go's escape analysis
// that was causing b to escape and be heap allocated.
// See issue 23382.
// TODO: once issue 7921 is fixed, this should be reverted to
// just "b.addr = b".
b.addr = (*StringBuilder)(noescape(unsafe.Pointer(b)))
} else if b.addr != b {
panic("strings: illegal use of non-zero Builder copied by value")
}
}
// String returns the accumulated string.
func (b *StringBuilder) String() string {
return *(*string)(unsafe.Pointer(&b.buf))
}
// Len returns the number of accumulated bytes; b.Len() == len(b.String()).
func (b *StringBuilder) Len() int { return len(b.buf) }
// Reset resets the Builder to be empty.
func (b *StringBuilder) Reset() {
b.addr = nil
b.buf = nil
}
// grow copies the buffer to a new, larger buffer so that there are at least n
// bytes of capacity beyond len(b.buf).
func (b *StringBuilder) grow(n int) {
buf := make([]byte, len(b.buf), 2*cap(b.buf)+n)
copy(buf, b.buf)
b.buf = buf
}
// Grow grows b's capacity, if necessary, to guarantee space for
// another n bytes. After Grow(n), at least n bytes can be written to b
// without another allocation. If n is negative, Grow panics.
func (b *StringBuilder) Grow(n int) {
b.copyCheck()
if n < 0 {
panic("strings.Builder.Grow: negative count")
}
if cap(b.buf)-len(b.buf) < n {
b.grow(n)
}
}
// Write appends the contents of p to b's buffer.
// Write always returns len(p), nil.
func (b *StringBuilder) Write(p []byte) (int, error) {
b.copyCheck()
b.buf = append(b.buf, p...)
return len(p), nil
}
// WriteByte appends the byte c to b's buffer.
// The returned error is always nil.
func (b *StringBuilder) WriteByte(c byte) error {
b.copyCheck()
b.buf = append(b.buf, c)
return nil
}
// WriteRune appends the UTF-8 encoding of Unicode code point r to b's buffer.
// It returns the length of r and a nil error.
func (b *StringBuilder) WriteRune(r rune) (int, error) {
b.copyCheck()
if r < utf8.RuneSelf {
b.buf = append(b.buf, byte(r))
return 1, nil
}
l := len(b.buf)
if cap(b.buf)-l < utf8.UTFMax {
b.grow(utf8.UTFMax)
}
n := utf8.EncodeRune(b.buf[l:l+utf8.UTFMax], r)
b.buf = b.buf[:l+n]
return n, nil
}
// WriteString appends the contents of s to b's buffer.
// It returns the length of s and a nil error.
func (b *StringBuilder) WriteString(s string) (int, error) {
b.copyCheck()
b.buf = append(b.buf, s...)
return len(s), nil
}

42
vendor/xorm.io/builder/writer.go generated vendored Normal file
View file

@ -0,0 +1,42 @@
// Copyright 2019 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 builder
import (
"io"
"strings"
)
// Writer defines the interface
type Writer interface {
io.Writer
Append(...interface{})
}
var _ Writer = NewWriter()
// BytesWriter implments Writer and save SQL in bytes.Buffer
type BytesWriter struct {
*strings.Builder
args []interface{}
}
// NewWriter creates a new string writer
func NewWriter() *BytesWriter {
w := &BytesWriter{
Builder: &strings.Builder{},
}
return w
}
// Append appends args to Writer
func (w *BytesWriter) Append(args ...interface{}) {
w.args = append(w.args, args...)
}
// Args returns args
func (w *BytesWriter) Args() []interface{} {
return w.args
}