Update xorm to latest version and fix correct `user` table referencing in sql (#4473)
parent
1e2da5d396
commit
0c59edaafa
@ -0,0 +1,119 @@ |
||||
// 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,113 @@ |
||||
// Copyright 2018 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" |
||||
"reflect" |
||||
"strings" |
||||
|
||||
"github.com/go-xorm/core" |
||||
) |
||||
|
||||
// TableNameWithSchema will automatically add schema prefix on table name
|
||||
func (engine *Engine) tbNameWithSchema(v string) string { |
||||
// Add schema name as prefix of table name.
|
||||
// Only for postgres database.
|
||||
if engine.dialect.DBType() == core.POSTGRES && |
||||
engine.dialect.URI().Schema != "" && |
||||
engine.dialect.URI().Schema != postgresPublicSchema && |
||||
strings.Index(v, ".") == -1 { |
||||
return engine.dialect.URI().Schema + "." + v |
||||
} |
||||
return v |
||||
} |
||||
|
||||
// TableName returns table name with schema prefix if has
|
||||
func (engine *Engine) TableName(bean interface{}, includeSchema ...bool) string { |
||||
tbName := engine.tbNameNoSchema(bean) |
||||
if len(includeSchema) > 0 && includeSchema[0] { |
||||
tbName = engine.tbNameWithSchema(tbName) |
||||
} |
||||
|
||||
return tbName |
||||
} |
||||
|
||||
// tbName get some table's table name
|
||||
func (session *Session) tbNameNoSchema(table *core.Table) string { |
||||
if len(session.statement.AltTableName) > 0 { |
||||
return session.statement.AltTableName |
||||
} |
||||
|
||||
return table.Name |
||||
} |
||||
|
||||
func (engine *Engine) tbNameForMap(v reflect.Value) string { |
||||
if v.Type().Implements(tpTableName) { |
||||
return v.Interface().(TableName).TableName() |
||||
} |
||||
if v.Kind() == reflect.Ptr { |
||||
v = v.Elem() |
||||
if v.Type().Implements(tpTableName) { |
||||
return v.Interface().(TableName).TableName() |
||||
} |
||||
} |
||||
|
||||
return engine.TableMapper.Obj2Table(v.Type().Name()) |
||||
} |
||||
|
||||
func (engine *Engine) tbNameNoSchema(tablename interface{}) string { |
||||
switch tablename.(type) { |
||||
case []string: |
||||
t := tablename.([]string) |
||||
if len(t) > 1 { |
||||
return fmt.Sprintf("%v AS %v", engine.Quote(t[0]), engine.Quote(t[1])) |
||||
} else if len(t) == 1 { |
||||
return engine.Quote(t[0]) |
||||
} |
||||
case []interface{}: |
||||
t := tablename.([]interface{}) |
||||
l := len(t) |
||||
var table string |
||||
if l > 0 { |
||||
f := t[0] |
||||
switch f.(type) { |
||||
case string: |
||||
table = f.(string) |
||||
case TableName: |
||||
table = f.(TableName).TableName() |
||||
default: |
||||
v := rValue(f) |
||||
t := v.Type() |
||||
if t.Kind() == reflect.Struct { |
||||
table = engine.tbNameForMap(v) |
||||
} else { |
||||
table = engine.Quote(fmt.Sprintf("%v", f)) |
||||
} |
||||
} |
||||
} |
||||
if l > 1 { |
||||
return fmt.Sprintf("%v AS %v", engine.Quote(table), |
||||
engine.Quote(fmt.Sprintf("%v", t[1]))) |
||||
} else if l == 1 { |
||||
return engine.Quote(table) |
||||
} |
||||
case TableName: |
||||
return tablename.(TableName).TableName() |
||||
case string: |
||||
return tablename.(string) |
||||
case reflect.Value: |
||||
v := tablename.(reflect.Value) |
||||
return engine.tbNameForMap(v) |
||||
default: |
||||
v := rValue(tablename) |
||||
t := v.Type() |
||||
if t.Kind() == reflect.Struct { |
||||
return engine.tbNameForMap(v) |
||||
} |
||||
return engine.Quote(fmt.Sprintf("%v", tablename)) |
||||
} |
||||
return "" |
||||
} |
Loading…
Reference in new issue