mirror of https://github.com/go-gitea/gitea.git
Fix label count (#8267)
* fix label count * fix vendor * fix import order * update xorm to fix bug * fix tests * fix mssql bugpull/8263/head^2
parent
7cccada51e
commit
29dda47cbb
@ -1,19 +1,20 @@
|
|||||||
module github.com/go-xorm/xorm
|
module github.com/go-xorm/xorm
|
||||||
|
|
||||||
|
go 1.11
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/cockroachdb/apd v1.1.0 // indirect
|
github.com/cockroachdb/apd v1.1.0 // indirect
|
||||||
github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4
|
github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4
|
||||||
github.com/go-sql-driver/mysql v1.4.1
|
github.com/go-sql-driver/mysql v1.4.1
|
||||||
|
github.com/gofrs/uuid v3.2.0+incompatible // indirect
|
||||||
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 // indirect
|
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 // indirect
|
||||||
github.com/jackc/pgx v3.3.0+incompatible
|
github.com/jackc/pgx v3.6.0+incompatible
|
||||||
github.com/kr/pretty v0.1.0 // indirect
|
|
||||||
github.com/lib/pq v1.0.0
|
github.com/lib/pq v1.0.0
|
||||||
github.com/mattn/go-sqlite3 v1.10.0
|
github.com/mattn/go-sqlite3 v1.10.0
|
||||||
github.com/pkg/errors v0.8.1 // indirect
|
github.com/pkg/errors v0.8.1 // indirect
|
||||||
github.com/satori/go.uuid v1.2.0 // indirect
|
|
||||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 // indirect
|
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 // indirect
|
||||||
github.com/stretchr/testify v1.3.0
|
github.com/stretchr/testify v1.3.0
|
||||||
github.com/ziutek/mymysql v1.5.4
|
github.com/ziutek/mymysql v1.5.4
|
||||||
xorm.io/builder v0.3.5
|
xorm.io/builder v0.3.6
|
||||||
xorm.io/core v0.7.0
|
xorm.io/core v0.7.0
|
||||||
)
|
)
|
||||||
|
@ -0,0 +1,97 @@
|
|||||||
|
// 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 xorm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"xorm.io/builder"
|
||||||
|
"xorm.io/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (statement *Statement) writeArg(w *builder.BytesWriter, arg interface{}) error {
|
||||||
|
switch argv := arg.(type) {
|
||||||
|
case string:
|
||||||
|
if _, err := w.WriteString("'" + argv + "'"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case bool:
|
||||||
|
if statement.Engine.dialect.DBType() == core.MSSQL {
|
||||||
|
if argv {
|
||||||
|
if _, err := w.WriteString("1"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if _, err := w.WriteString("0"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if argv {
|
||||||
|
if _, err := w.WriteString("true"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if _, err := w.WriteString("false"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case *builder.Builder:
|
||||||
|
if _, err := w.WriteString("("); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := argv.WriteTo(w); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := w.WriteString(")"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if _, err := w.WriteString(fmt.Sprintf("%v", argv)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (statement *Statement) writeArgs(w *builder.BytesWriter, args []interface{}) error {
|
||||||
|
for i, arg := range args {
|
||||||
|
if err := statement.writeArg(w, arg); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if i+1 != len(args) {
|
||||||
|
if _, err := w.WriteString(","); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeStrings(w *builder.BytesWriter, cols []string, leftQuote, rightQuote string) error {
|
||||||
|
for i, colName := range cols {
|
||||||
|
if len(leftQuote) > 0 && colName[0] != '`' {
|
||||||
|
if _, err := w.WriteString(leftQuote); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, err := w.WriteString(colName); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(rightQuote) > 0 && colName[len(colName)-1] != '`' {
|
||||||
|
if _, err := w.WriteString(rightQuote); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if i+1 != len(cols) {
|
||||||
|
if _, err := w.WriteString(","); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
// 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 xorm
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
type columnMap []string
|
||||||
|
|
||||||
|
func (m columnMap) contain(colName string) bool {
|
||||||
|
if len(m) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
n := len(colName)
|
||||||
|
for _, mk := range m {
|
||||||
|
if len(mk) != n {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.EqualFold(mk, colName) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *columnMap) add(colName string) bool {
|
||||||
|
if m.contain(colName) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
*m = append(*m, colName)
|
||||||
|
return true
|
||||||
|
}
|
@ -0,0 +1,112 @@
|
|||||||
|
// 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 xorm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"xorm.io/builder"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ErrUnsupportedExprType struct {
|
||||||
|
tp string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err ErrUnsupportedExprType) Error() string {
|
||||||
|
return fmt.Sprintf("Unsupported expression type: %v", err.tp)
|
||||||
|
}
|
||||||
|
|
||||||
|
type exprParam struct {
|
||||||
|
colName string
|
||||||
|
arg interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type exprParams struct {
|
||||||
|
colNames []string
|
||||||
|
args []interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (exprs *exprParams) Len() int {
|
||||||
|
return len(exprs.colNames)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (exprs *exprParams) addParam(colName string, arg interface{}) {
|
||||||
|
exprs.colNames = append(exprs.colNames, colName)
|
||||||
|
exprs.args = append(exprs.args, arg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (exprs *exprParams) isColExist(colName string) bool {
|
||||||
|
for _, name := range exprs.colNames {
|
||||||
|
if strings.EqualFold(trimQuote(name), trimQuote(colName)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (exprs *exprParams) getByName(colName string) (exprParam, bool) {
|
||||||
|
for i, name := range exprs.colNames {
|
||||||
|
if strings.EqualFold(name, colName) {
|
||||||
|
return exprParam{name, exprs.args[i]}, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return exprParam{}, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (exprs *exprParams) writeArgs(w *builder.BytesWriter) error {
|
||||||
|
for _, expr := range exprs.args {
|
||||||
|
switch arg := expr.(type) {
|
||||||
|
case *builder.Builder:
|
||||||
|
if _, err := w.WriteString("("); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := arg.WriteTo(w); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := w.WriteString(")"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if _, err := w.WriteString(fmt.Sprintf("%v", arg)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (exprs *exprParams) writeNameArgs(w *builder.BytesWriter) error {
|
||||||
|
for i, colName := range exprs.colNames {
|
||||||
|
if _, err := w.WriteString(colName); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := w.WriteString("="); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch arg := exprs.args[i].(type) {
|
||||||
|
case *builder.Builder:
|
||||||
|
if _, err := w.WriteString("("); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := arg.WriteTo(w); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := w.WriteString("("); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
w.Append(exprs.args[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
if i+1 != len(exprs.colNames) {
|
||||||
|
if _, err := w.WriteString(","); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
// 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 xorm
|
||||||
|
|
||||||
|
func trimQuote(s string) string {
|
||||||
|
if len(s) == 0 {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
if s[0] == '`' {
|
||||||
|
s = s[1:]
|
||||||
|
}
|
||||||
|
if len(s) > 0 && s[len(s)-1] == '`' {
|
||||||
|
return s[:len(s)-1]
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
@ -1 +1 @@
|
|||||||
go test -db=mssql -conn_str="server=localhost;user id=sa;password=yourStrong(!)Password;database=xorm_test"
|
go test -db=mssql -conn_str="server=localhost;user id=sa;password=MwantsaSecurePassword1;database=xorm_test"
|
@ -1,37 +1,90 @@
|
|||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
name: go1.10
|
||||||
|
|
||||||
workspace:
|
workspace:
|
||||||
base: /go
|
base: /go
|
||||||
path: src/github.com/go-xorm/builder
|
path: src/xorm.io/builder
|
||||||
|
|
||||||
clone:
|
steps:
|
||||||
git:
|
- name: test
|
||||||
image: plugins/git:next
|
pull: default
|
||||||
depth: 50
|
image: golang:1.10
|
||||||
tags: true
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
GO_VERSION:
|
|
||||||
- 1.8
|
|
||||||
- 1.9
|
|
||||||
- 1.10
|
|
||||||
- 1.11
|
|
||||||
|
|
||||||
pipeline:
|
|
||||||
test:
|
|
||||||
image: golang:${GO_VERSION}
|
|
||||||
commands:
|
commands:
|
||||||
- go get -u github.com/golang/lint/golint
|
- go get -u golang.org/x/lint/golint
|
||||||
- go get -u github.com/stretchr/testify/assert
|
- go get -u github.com/stretchr/testify/assert
|
||||||
- go get -u github.com/go-xorm/sqlfiddle
|
- go get -u github.com/go-xorm/sqlfiddle
|
||||||
- golint ./...
|
- golint ./...
|
||||||
|
- go vet
|
||||||
|
- go test -v -race -coverprofile=coverage.txt -covermode=atomic
|
||||||
|
when:
|
||||||
|
event:
|
||||||
|
- push
|
||||||
|
- tag
|
||||||
|
- pull_request
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
name: go1.11
|
||||||
|
|
||||||
|
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
|
- go test -v -race -coverprofile=coverage.txt -covermode=atomic
|
||||||
|
environment:
|
||||||
|
GOPROXY: https://goproxy.cn
|
||||||
|
GO111MODULE: "on"
|
||||||
when:
|
when:
|
||||||
event: [ push, tag, pull_request ]
|
event:
|
||||||
|
- push
|
||||||
codecov:
|
- tag
|
||||||
image: robertstettner/drone-codecov
|
- pull_request
|
||||||
group: build
|
|
||||||
secrets: [ codecov_token ]
|
---
|
||||||
files:
|
kind: pipeline
|
||||||
- coverage.txt
|
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:
|
when:
|
||||||
event: [ push, pull_request ]
|
event:
|
||||||
|
- push
|
||||||
|
- tag
|
||||||
|
- pull_request
|
@ -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
|
||||||
|
}
|
@ -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
|
|
||||||
}
|
|
@ -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
|
||||||
|
}
|
Loading…
Reference in New Issue