mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-11-01 08:12:26 -05:00
Pg to bun (#148)
* start moving to bun * changing more stuff * more * and yet more * tests passing * seems stable now * more big changes * small fix * little fixes
This commit is contained in:
parent
071eca20ce
commit
2dc9fc1626
713 changed files with 98694 additions and 22704 deletions
178
vendor/github.com/uptrace/bun/dialect/append.go
generated
vendored
Normal file
178
vendor/github.com/uptrace/bun/dialect/append.go
generated
vendored
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
package dialect
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"math"
|
||||
"strconv"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/uptrace/bun/internal"
|
||||
"github.com/uptrace/bun/internal/parser"
|
||||
)
|
||||
|
||||
func AppendError(b []byte, err error) []byte {
|
||||
b = append(b, "?!("...)
|
||||
b = append(b, err.Error()...)
|
||||
b = append(b, ')')
|
||||
return b
|
||||
}
|
||||
|
||||
func AppendNull(b []byte) []byte {
|
||||
return append(b, "NULL"...)
|
||||
}
|
||||
|
||||
func AppendBool(b []byte, v bool) []byte {
|
||||
if v {
|
||||
return append(b, "TRUE"...)
|
||||
}
|
||||
return append(b, "FALSE"...)
|
||||
}
|
||||
|
||||
func AppendFloat32(b []byte, v float32) []byte {
|
||||
return appendFloat(b, float64(v), 32)
|
||||
}
|
||||
|
||||
func AppendFloat64(b []byte, v float64) []byte {
|
||||
return appendFloat(b, v, 64)
|
||||
}
|
||||
|
||||
func appendFloat(b []byte, v float64, bitSize int) []byte {
|
||||
switch {
|
||||
case math.IsNaN(v):
|
||||
return append(b, "'NaN'"...)
|
||||
case math.IsInf(v, 1):
|
||||
return append(b, "'Infinity'"...)
|
||||
case math.IsInf(v, -1):
|
||||
return append(b, "'-Infinity'"...)
|
||||
default:
|
||||
return strconv.AppendFloat(b, v, 'f', -1, bitSize)
|
||||
}
|
||||
}
|
||||
|
||||
func AppendString(b []byte, s string) []byte {
|
||||
b = append(b, '\'')
|
||||
for _, r := range s {
|
||||
if r == '\000' {
|
||||
continue
|
||||
}
|
||||
|
||||
if r == '\'' {
|
||||
b = append(b, '\'', '\'')
|
||||
continue
|
||||
}
|
||||
|
||||
if r < utf8.RuneSelf {
|
||||
b = append(b, byte(r))
|
||||
continue
|
||||
}
|
||||
|
||||
l := len(b)
|
||||
if cap(b)-l < utf8.UTFMax {
|
||||
b = append(b, make([]byte, utf8.UTFMax)...)
|
||||
}
|
||||
n := utf8.EncodeRune(b[l:l+utf8.UTFMax], r)
|
||||
b = b[:l+n]
|
||||
}
|
||||
b = append(b, '\'')
|
||||
return b
|
||||
}
|
||||
|
||||
func AppendBytes(b []byte, bytes []byte) []byte {
|
||||
if bytes == nil {
|
||||
return AppendNull(b)
|
||||
}
|
||||
|
||||
b = append(b, `'\x`...)
|
||||
|
||||
s := len(b)
|
||||
b = append(b, make([]byte, hex.EncodedLen(len(bytes)))...)
|
||||
hex.Encode(b[s:], bytes)
|
||||
|
||||
b = append(b, '\'')
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
func AppendTime(b []byte, tm time.Time) []byte {
|
||||
if tm.IsZero() {
|
||||
return AppendNull(b)
|
||||
}
|
||||
b = append(b, '\'')
|
||||
b = tm.UTC().AppendFormat(b, "2006-01-02 15:04:05.999999-07:00")
|
||||
b = append(b, '\'')
|
||||
return b
|
||||
}
|
||||
|
||||
func AppendJSON(b, jsonb []byte) []byte {
|
||||
b = append(b, '\'')
|
||||
|
||||
p := parser.New(jsonb)
|
||||
for p.Valid() {
|
||||
c := p.Read()
|
||||
switch c {
|
||||
case '"':
|
||||
b = append(b, '"')
|
||||
case '\'':
|
||||
b = append(b, "''"...)
|
||||
case '\000':
|
||||
continue
|
||||
case '\\':
|
||||
if p.SkipBytes([]byte("u0000")) {
|
||||
b = append(b, `\\u0000`...)
|
||||
} else {
|
||||
b = append(b, '\\')
|
||||
if p.Valid() {
|
||||
b = append(b, p.Read())
|
||||
}
|
||||
}
|
||||
default:
|
||||
b = append(b, c)
|
||||
}
|
||||
}
|
||||
|
||||
b = append(b, '\'')
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
func AppendIdent(b []byte, field string, quote byte) []byte {
|
||||
return appendIdent(b, internal.Bytes(field), quote)
|
||||
}
|
||||
|
||||
func appendIdent(b, src []byte, quote byte) []byte {
|
||||
var quoted bool
|
||||
loop:
|
||||
for _, c := range src {
|
||||
switch c {
|
||||
case '*':
|
||||
if !quoted {
|
||||
b = append(b, '*')
|
||||
continue loop
|
||||
}
|
||||
case '.':
|
||||
if quoted {
|
||||
b = append(b, quote)
|
||||
quoted = false
|
||||
}
|
||||
b = append(b, '.')
|
||||
continue loop
|
||||
}
|
||||
|
||||
if !quoted {
|
||||
b = append(b, quote)
|
||||
quoted = true
|
||||
}
|
||||
if c == quote {
|
||||
b = append(b, quote, quote)
|
||||
} else {
|
||||
b = append(b, c)
|
||||
}
|
||||
}
|
||||
if quoted {
|
||||
b = append(b, quote)
|
||||
}
|
||||
return b
|
||||
}
|
||||
26
vendor/github.com/uptrace/bun/dialect/dialect.go
generated
vendored
Normal file
26
vendor/github.com/uptrace/bun/dialect/dialect.go
generated
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
package dialect
|
||||
|
||||
type Name int
|
||||
|
||||
func (n Name) String() string {
|
||||
switch n {
|
||||
case PG:
|
||||
return "pg"
|
||||
case SQLite:
|
||||
return "sqlite"
|
||||
case MySQL5:
|
||||
return "mysql5"
|
||||
case MySQL8:
|
||||
return "mysql8"
|
||||
default:
|
||||
return "invalid"
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
Invalid Name = iota
|
||||
PG
|
||||
SQLite
|
||||
MySQL5
|
||||
MySQL8
|
||||
)
|
||||
22
vendor/github.com/uptrace/bun/dialect/feature/feature.go
generated
vendored
Normal file
22
vendor/github.com/uptrace/bun/dialect/feature/feature.go
generated
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
package feature
|
||||
|
||||
import "github.com/uptrace/bun/internal"
|
||||
|
||||
type Feature = internal.Flag
|
||||
|
||||
const DefaultFeatures = Returning | TableCascade
|
||||
|
||||
const (
|
||||
Returning Feature = 1 << iota
|
||||
DefaultPlaceholder
|
||||
DoubleColonCast
|
||||
ValuesRow
|
||||
UpdateMultiTable
|
||||
InsertTableAlias
|
||||
DeleteTableAlias
|
||||
AutoIncrement
|
||||
TableCascade
|
||||
TableIdentity
|
||||
TableTruncate
|
||||
OnDuplicateKey
|
||||
)
|
||||
24
vendor/github.com/uptrace/bun/dialect/pgdialect/LICENSE
generated
vendored
Normal file
24
vendor/github.com/uptrace/bun/dialect/pgdialect/LICENSE
generated
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
Copyright (c) 2021 Vladimir Mihailenco. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
303
vendor/github.com/uptrace/bun/dialect/pgdialect/append.go
generated
vendored
Normal file
303
vendor/github.com/uptrace/bun/dialect/pgdialect/append.go
generated
vendored
Normal file
|
|
@ -0,0 +1,303 @@
|
|||
package pgdialect
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/uptrace/bun/dialect"
|
||||
"github.com/uptrace/bun/schema"
|
||||
)
|
||||
|
||||
var (
|
||||
driverValuerType = reflect.TypeOf((*driver.Valuer)(nil)).Elem()
|
||||
|
||||
stringType = reflect.TypeOf((*string)(nil)).Elem()
|
||||
sliceStringType = reflect.TypeOf([]string(nil))
|
||||
|
||||
intType = reflect.TypeOf((*int)(nil)).Elem()
|
||||
sliceIntType = reflect.TypeOf([]int(nil))
|
||||
|
||||
int64Type = reflect.TypeOf((*int64)(nil)).Elem()
|
||||
sliceInt64Type = reflect.TypeOf([]int64(nil))
|
||||
|
||||
float64Type = reflect.TypeOf((*float64)(nil)).Elem()
|
||||
sliceFloat64Type = reflect.TypeOf([]float64(nil))
|
||||
)
|
||||
|
||||
func customAppender(typ reflect.Type) schema.AppenderFunc {
|
||||
switch typ.Kind() {
|
||||
case reflect.Uint32:
|
||||
return appendUint32ValueAsInt
|
||||
case reflect.Uint, reflect.Uint64:
|
||||
return appendUint64ValueAsInt
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func appendUint32ValueAsInt(fmter schema.Formatter, b []byte, v reflect.Value) []byte {
|
||||
return strconv.AppendInt(b, int64(int32(v.Uint())), 10)
|
||||
}
|
||||
|
||||
func appendUint64ValueAsInt(fmter schema.Formatter, b []byte, v reflect.Value) []byte {
|
||||
return strconv.AppendInt(b, int64(v.Uint()), 10)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
func arrayAppend(fmter schema.Formatter, b []byte, v interface{}) []byte {
|
||||
switch v := v.(type) {
|
||||
case int64:
|
||||
return strconv.AppendInt(b, v, 10)
|
||||
case float64:
|
||||
return dialect.AppendFloat64(b, v)
|
||||
case bool:
|
||||
return dialect.AppendBool(b, v)
|
||||
case []byte:
|
||||
return dialect.AppendBytes(b, v)
|
||||
case string:
|
||||
return arrayAppendString(b, v)
|
||||
case time.Time:
|
||||
return dialect.AppendTime(b, v)
|
||||
default:
|
||||
err := fmt.Errorf("pgdialect: can't append %T", v)
|
||||
return dialect.AppendError(b, err)
|
||||
}
|
||||
}
|
||||
|
||||
func arrayElemAppender(typ reflect.Type) schema.AppenderFunc {
|
||||
if typ.Kind() == reflect.String {
|
||||
return arrayAppendStringValue
|
||||
}
|
||||
if typ.Implements(driverValuerType) {
|
||||
return arrayAppendDriverValue
|
||||
}
|
||||
return schema.Appender(typ, customAppender)
|
||||
}
|
||||
|
||||
func arrayAppendStringValue(fmter schema.Formatter, b []byte, v reflect.Value) []byte {
|
||||
return arrayAppendString(b, v.String())
|
||||
}
|
||||
|
||||
func arrayAppendDriverValue(fmter schema.Formatter, b []byte, v reflect.Value) []byte {
|
||||
iface, err := v.Interface().(driver.Valuer).Value()
|
||||
if err != nil {
|
||||
return dialect.AppendError(b, err)
|
||||
}
|
||||
return arrayAppend(fmter, b, iface)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
func arrayAppender(typ reflect.Type) schema.AppenderFunc {
|
||||
kind := typ.Kind()
|
||||
if kind == reflect.Ptr {
|
||||
typ = typ.Elem()
|
||||
kind = typ.Kind()
|
||||
}
|
||||
|
||||
switch kind {
|
||||
case reflect.Slice, reflect.Array:
|
||||
// ok:
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
elemType := typ.Elem()
|
||||
|
||||
if kind == reflect.Slice {
|
||||
switch elemType {
|
||||
case stringType:
|
||||
return appendStringSliceValue
|
||||
case intType:
|
||||
return appendIntSliceValue
|
||||
case int64Type:
|
||||
return appendInt64SliceValue
|
||||
case float64Type:
|
||||
return appendFloat64SliceValue
|
||||
}
|
||||
}
|
||||
|
||||
appendElem := arrayElemAppender(elemType)
|
||||
if appendElem == nil {
|
||||
panic(fmt.Errorf("pgdialect: %s is not supported", typ))
|
||||
}
|
||||
|
||||
return func(fmter schema.Formatter, b []byte, v reflect.Value) []byte {
|
||||
kind := v.Kind()
|
||||
switch kind {
|
||||
case reflect.Ptr, reflect.Slice:
|
||||
if v.IsNil() {
|
||||
return dialect.AppendNull(b)
|
||||
}
|
||||
}
|
||||
|
||||
if kind == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
}
|
||||
|
||||
b = append(b, '\'')
|
||||
|
||||
b = append(b, '{')
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
elem := v.Index(i)
|
||||
b = appendElem(fmter, b, elem)
|
||||
b = append(b, ',')
|
||||
}
|
||||
if v.Len() > 0 {
|
||||
b[len(b)-1] = '}' // Replace trailing comma.
|
||||
} else {
|
||||
b = append(b, '}')
|
||||
}
|
||||
|
||||
b = append(b, '\'')
|
||||
|
||||
return b
|
||||
}
|
||||
}
|
||||
|
||||
func appendStringSliceValue(fmter schema.Formatter, b []byte, v reflect.Value) []byte {
|
||||
ss := v.Convert(sliceStringType).Interface().([]string)
|
||||
return appendStringSlice(b, ss)
|
||||
}
|
||||
|
||||
func appendStringSlice(b []byte, ss []string) []byte {
|
||||
if ss == nil {
|
||||
return dialect.AppendNull(b)
|
||||
}
|
||||
|
||||
b = append(b, '\'')
|
||||
|
||||
b = append(b, '{')
|
||||
for _, s := range ss {
|
||||
b = arrayAppendString(b, s)
|
||||
b = append(b, ',')
|
||||
}
|
||||
if len(ss) > 0 {
|
||||
b[len(b)-1] = '}' // Replace trailing comma.
|
||||
} else {
|
||||
b = append(b, '}')
|
||||
}
|
||||
|
||||
b = append(b, '\'')
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
func appendIntSliceValue(fmter schema.Formatter, b []byte, v reflect.Value) []byte {
|
||||
ints := v.Convert(sliceIntType).Interface().([]int)
|
||||
return appendIntSlice(b, ints)
|
||||
}
|
||||
|
||||
func appendIntSlice(b []byte, ints []int) []byte {
|
||||
if ints == nil {
|
||||
return dialect.AppendNull(b)
|
||||
}
|
||||
|
||||
b = append(b, '\'')
|
||||
|
||||
b = append(b, '{')
|
||||
for _, n := range ints {
|
||||
b = strconv.AppendInt(b, int64(n), 10)
|
||||
b = append(b, ',')
|
||||
}
|
||||
if len(ints) > 0 {
|
||||
b[len(b)-1] = '}' // Replace trailing comma.
|
||||
} else {
|
||||
b = append(b, '}')
|
||||
}
|
||||
|
||||
b = append(b, '\'')
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
func appendInt64SliceValue(fmter schema.Formatter, b []byte, v reflect.Value) []byte {
|
||||
ints := v.Convert(sliceInt64Type).Interface().([]int64)
|
||||
return appendInt64Slice(b, ints)
|
||||
}
|
||||
|
||||
func appendInt64Slice(b []byte, ints []int64) []byte {
|
||||
if ints == nil {
|
||||
return dialect.AppendNull(b)
|
||||
}
|
||||
|
||||
b = append(b, '\'')
|
||||
|
||||
b = append(b, '{')
|
||||
for _, n := range ints {
|
||||
b = strconv.AppendInt(b, n, 10)
|
||||
b = append(b, ',')
|
||||
}
|
||||
if len(ints) > 0 {
|
||||
b[len(b)-1] = '}' // Replace trailing comma.
|
||||
} else {
|
||||
b = append(b, '}')
|
||||
}
|
||||
|
||||
b = append(b, '\'')
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
func appendFloat64SliceValue(fmter schema.Formatter, b []byte, v reflect.Value) []byte {
|
||||
floats := v.Convert(sliceFloat64Type).Interface().([]float64)
|
||||
return appendFloat64Slice(b, floats)
|
||||
}
|
||||
|
||||
func appendFloat64Slice(b []byte, floats []float64) []byte {
|
||||
if floats == nil {
|
||||
return dialect.AppendNull(b)
|
||||
}
|
||||
|
||||
b = append(b, '\'')
|
||||
|
||||
b = append(b, '{')
|
||||
for _, n := range floats {
|
||||
b = dialect.AppendFloat64(b, n)
|
||||
b = append(b, ',')
|
||||
}
|
||||
if len(floats) > 0 {
|
||||
b[len(b)-1] = '}' // Replace trailing comma.
|
||||
} else {
|
||||
b = append(b, '}')
|
||||
}
|
||||
|
||||
b = append(b, '\'')
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
func arrayAppendString(b []byte, s string) []byte {
|
||||
b = append(b, '"')
|
||||
for _, r := range s {
|
||||
switch r {
|
||||
case 0:
|
||||
// ignore
|
||||
case '\'':
|
||||
b = append(b, "'''"...)
|
||||
case '"':
|
||||
b = append(b, '\\', '"')
|
||||
case '\\':
|
||||
b = append(b, '\\', '\\')
|
||||
default:
|
||||
if r < utf8.RuneSelf {
|
||||
b = append(b, byte(r))
|
||||
break
|
||||
}
|
||||
l := len(b)
|
||||
if cap(b)-l < utf8.UTFMax {
|
||||
b = append(b, make([]byte, utf8.UTFMax)...)
|
||||
}
|
||||
n := utf8.EncodeRune(b[l:l+utf8.UTFMax], r)
|
||||
b = b[:l+n]
|
||||
}
|
||||
}
|
||||
b = append(b, '"')
|
||||
return b
|
||||
}
|
||||
65
vendor/github.com/uptrace/bun/dialect/pgdialect/array.go
generated
vendored
Normal file
65
vendor/github.com/uptrace/bun/dialect/pgdialect/array.go
generated
vendored
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
package pgdialect
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/uptrace/bun/schema"
|
||||
)
|
||||
|
||||
type ArrayValue struct {
|
||||
v reflect.Value
|
||||
|
||||
append schema.AppenderFunc
|
||||
scan schema.ScannerFunc
|
||||
}
|
||||
|
||||
// Array accepts a slice and returns a wrapper for working with PostgreSQL
|
||||
// array data type.
|
||||
//
|
||||
// For struct fields you can use array tag:
|
||||
//
|
||||
// Emails []string `bun:",array"`
|
||||
func Array(vi interface{}) *ArrayValue {
|
||||
v := reflect.ValueOf(vi)
|
||||
if !v.IsValid() {
|
||||
panic(fmt.Errorf("bun: Array(nil)"))
|
||||
}
|
||||
|
||||
return &ArrayValue{
|
||||
v: v,
|
||||
|
||||
append: arrayAppender(v.Type()),
|
||||
scan: arrayScanner(v.Type()),
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
_ schema.QueryAppender = (*ArrayValue)(nil)
|
||||
_ sql.Scanner = (*ArrayValue)(nil)
|
||||
)
|
||||
|
||||
func (a *ArrayValue) AppendQuery(fmter schema.Formatter, b []byte) ([]byte, error) {
|
||||
if a.append == nil {
|
||||
panic(fmt.Errorf("bun: Array(unsupported %s)", a.v.Type()))
|
||||
}
|
||||
return a.append(fmter, b, a.v), nil
|
||||
}
|
||||
|
||||
func (a *ArrayValue) Scan(src interface{}) error {
|
||||
if a.scan == nil {
|
||||
return fmt.Errorf("bun: Array(unsupported %s)", a.v.Type())
|
||||
}
|
||||
if a.v.Kind() != reflect.Ptr {
|
||||
return fmt.Errorf("bun: Array(non-pointer %s)", a.v.Type())
|
||||
}
|
||||
return a.scan(a.v, src)
|
||||
}
|
||||
|
||||
func (a *ArrayValue) Value() interface{} {
|
||||
if a.v.IsValid() {
|
||||
return a.v.Interface()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
146
vendor/github.com/uptrace/bun/dialect/pgdialect/array_parser.go
generated
vendored
Normal file
146
vendor/github.com/uptrace/bun/dialect/pgdialect/array_parser.go
generated
vendored
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
package pgdialect
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
type arrayParser struct {
|
||||
b []byte
|
||||
i int
|
||||
|
||||
buf []byte
|
||||
err error
|
||||
}
|
||||
|
||||
func newArrayParser(b []byte) *arrayParser {
|
||||
p := &arrayParser{
|
||||
b: b,
|
||||
i: 1,
|
||||
}
|
||||
if len(b) < 2 || b[0] != '{' || b[len(b)-1] != '}' {
|
||||
p.err = fmt.Errorf("bun: can't parse array: %q", b)
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *arrayParser) NextElem() ([]byte, error) {
|
||||
if p.err != nil {
|
||||
return nil, p.err
|
||||
}
|
||||
|
||||
c, err := p.readByte()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch c {
|
||||
case '}':
|
||||
return nil, io.EOF
|
||||
case '"':
|
||||
b, err := p.readSubstring()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if p.peek() == ',' {
|
||||
p.skipNext()
|
||||
}
|
||||
|
||||
return b, nil
|
||||
default:
|
||||
b := p.readSimple()
|
||||
if bytes.Equal(b, []byte("NULL")) {
|
||||
b = nil
|
||||
}
|
||||
|
||||
if p.peek() == ',' {
|
||||
p.skipNext()
|
||||
}
|
||||
|
||||
return b, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (p *arrayParser) readSimple() []byte {
|
||||
p.unreadByte()
|
||||
|
||||
if i := bytes.IndexByte(p.b[p.i:], ','); i >= 0 {
|
||||
b := p.b[p.i : p.i+i]
|
||||
p.i += i
|
||||
return b
|
||||
}
|
||||
|
||||
b := p.b[p.i : len(p.b)-1]
|
||||
p.i = len(p.b) - 1
|
||||
return b
|
||||
}
|
||||
|
||||
func (p *arrayParser) readSubstring() ([]byte, error) {
|
||||
c, err := p.readByte()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p.buf = p.buf[:0]
|
||||
for {
|
||||
if c == '"' {
|
||||
break
|
||||
}
|
||||
|
||||
next, err := p.readByte()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if c == '\\' {
|
||||
switch next {
|
||||
case '\\', '"':
|
||||
p.buf = append(p.buf, next)
|
||||
|
||||
c, err = p.readByte()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
default:
|
||||
p.buf = append(p.buf, '\\')
|
||||
c = next
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
p.buf = append(p.buf, c)
|
||||
c = next
|
||||
}
|
||||
|
||||
return p.buf, nil
|
||||
}
|
||||
|
||||
func (p *arrayParser) valid() bool {
|
||||
return p.i < len(p.b)
|
||||
}
|
||||
|
||||
func (p *arrayParser) readByte() (byte, error) {
|
||||
if p.valid() {
|
||||
c := p.b[p.i]
|
||||
p.i++
|
||||
return c, nil
|
||||
}
|
||||
return 0, io.EOF
|
||||
}
|
||||
|
||||
func (p *arrayParser) unreadByte() {
|
||||
p.i--
|
||||
}
|
||||
|
||||
func (p *arrayParser) peek() byte {
|
||||
if p.valid() {
|
||||
return p.b[p.i]
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (p *arrayParser) skipNext() {
|
||||
p.i++
|
||||
}
|
||||
302
vendor/github.com/uptrace/bun/dialect/pgdialect/array_scan.go
generated
vendored
Normal file
302
vendor/github.com/uptrace/bun/dialect/pgdialect/array_scan.go
generated
vendored
Normal file
|
|
@ -0,0 +1,302 @@
|
|||
package pgdialect
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"strconv"
|
||||
|
||||
"github.com/uptrace/bun/internal"
|
||||
"github.com/uptrace/bun/schema"
|
||||
)
|
||||
|
||||
func arrayScanner(typ reflect.Type) schema.ScannerFunc {
|
||||
kind := typ.Kind()
|
||||
if kind == reflect.Ptr {
|
||||
typ = typ.Elem()
|
||||
kind = typ.Kind()
|
||||
}
|
||||
|
||||
switch kind {
|
||||
case reflect.Slice, reflect.Array:
|
||||
// ok:
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
elemType := typ.Elem()
|
||||
|
||||
if kind == reflect.Slice {
|
||||
switch elemType {
|
||||
case stringType:
|
||||
return scanStringSliceValue
|
||||
case intType:
|
||||
return scanIntSliceValue
|
||||
case int64Type:
|
||||
return scanInt64SliceValue
|
||||
case float64Type:
|
||||
return scanFloat64SliceValue
|
||||
}
|
||||
}
|
||||
|
||||
scanElem := schema.Scanner(elemType)
|
||||
return func(dest reflect.Value, src interface{}) error {
|
||||
dest = reflect.Indirect(dest)
|
||||
if !dest.CanSet() {
|
||||
return fmt.Errorf("bun: Scan(non-settable %s)", dest.Type())
|
||||
}
|
||||
|
||||
kind := dest.Kind()
|
||||
|
||||
if src == nil {
|
||||
if kind != reflect.Slice || !dest.IsNil() {
|
||||
dest.Set(reflect.Zero(dest.Type()))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if kind == reflect.Slice {
|
||||
if dest.IsNil() {
|
||||
dest.Set(reflect.MakeSlice(dest.Type(), 0, 0))
|
||||
} else if dest.Len() > 0 {
|
||||
dest.Set(dest.Slice(0, 0))
|
||||
}
|
||||
}
|
||||
|
||||
b, err := toBytes(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p := newArrayParser(b)
|
||||
nextValue := internal.MakeSliceNextElemFunc(dest)
|
||||
for {
|
||||
elem, err := p.NextElem()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
elemValue := nextValue()
|
||||
if err := scanElem(elemValue, elem); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func scanStringSliceValue(dest reflect.Value, src interface{}) error {
|
||||
dest = reflect.Indirect(dest)
|
||||
if !dest.CanSet() {
|
||||
return fmt.Errorf("bun: Scan(non-settable %s)", dest.Type())
|
||||
}
|
||||
|
||||
slice, err := decodeStringSlice(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dest.Set(reflect.ValueOf(slice))
|
||||
return nil
|
||||
}
|
||||
|
||||
func decodeStringSlice(src interface{}) ([]string, error) {
|
||||
if src == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
b, err := toBytes(src)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
slice := make([]string, 0)
|
||||
|
||||
p := newArrayParser(b)
|
||||
for {
|
||||
elem, err := p.NextElem()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
slice = append(slice, string(elem))
|
||||
}
|
||||
|
||||
return slice, nil
|
||||
}
|
||||
|
||||
func scanIntSliceValue(dest reflect.Value, src interface{}) error {
|
||||
dest = reflect.Indirect(dest)
|
||||
if !dest.CanSet() {
|
||||
return fmt.Errorf("bun: Scan(non-settable %s)", dest.Type())
|
||||
}
|
||||
|
||||
slice, err := decodeIntSlice(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dest.Set(reflect.ValueOf(slice))
|
||||
return nil
|
||||
}
|
||||
|
||||
func decodeIntSlice(src interface{}) ([]int, error) {
|
||||
if src == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
b, err := toBytes(src)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
slice := make([]int, 0)
|
||||
|
||||
p := newArrayParser(b)
|
||||
for {
|
||||
elem, err := p.NextElem()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if elem == nil {
|
||||
slice = append(slice, 0)
|
||||
continue
|
||||
}
|
||||
|
||||
n, err := strconv.Atoi(bytesToString(elem))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
slice = append(slice, n)
|
||||
}
|
||||
|
||||
return slice, nil
|
||||
}
|
||||
|
||||
func scanInt64SliceValue(dest reflect.Value, src interface{}) error {
|
||||
dest = reflect.Indirect(dest)
|
||||
if !dest.CanSet() {
|
||||
return fmt.Errorf("bun: Scan(non-settable %s)", dest.Type())
|
||||
}
|
||||
|
||||
slice, err := decodeInt64Slice(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dest.Set(reflect.ValueOf(slice))
|
||||
return nil
|
||||
}
|
||||
|
||||
func decodeInt64Slice(src interface{}) ([]int64, error) {
|
||||
if src == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
b, err := toBytes(src)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
slice := make([]int64, 0)
|
||||
|
||||
p := newArrayParser(b)
|
||||
for {
|
||||
elem, err := p.NextElem()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if elem == nil {
|
||||
slice = append(slice, 0)
|
||||
continue
|
||||
}
|
||||
|
||||
n, err := strconv.ParseInt(bytesToString(elem), 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
slice = append(slice, n)
|
||||
}
|
||||
|
||||
return slice, nil
|
||||
}
|
||||
|
||||
func scanFloat64SliceValue(dest reflect.Value, src interface{}) error {
|
||||
dest = reflect.Indirect(dest)
|
||||
if !dest.CanSet() {
|
||||
return fmt.Errorf("bun: Scan(non-settable %s)", dest.Type())
|
||||
}
|
||||
|
||||
slice, err := scanFloat64Slice(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dest.Set(reflect.ValueOf(slice))
|
||||
return nil
|
||||
}
|
||||
|
||||
func scanFloat64Slice(src interface{}) ([]float64, error) {
|
||||
if src == -1 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
b, err := toBytes(src)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
slice := make([]float64, 0)
|
||||
|
||||
p := newArrayParser(b)
|
||||
for {
|
||||
elem, err := p.NextElem()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if elem == nil {
|
||||
slice = append(slice, 0)
|
||||
continue
|
||||
}
|
||||
|
||||
n, err := strconv.ParseFloat(bytesToString(elem), 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
slice = append(slice, n)
|
||||
}
|
||||
|
||||
return slice, nil
|
||||
}
|
||||
|
||||
func toBytes(src interface{}) ([]byte, error) {
|
||||
switch src := src.(type) {
|
||||
case string:
|
||||
return stringToBytes(src), nil
|
||||
case []byte:
|
||||
return src, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("bun: got %T, wanted []byte or string", src)
|
||||
}
|
||||
}
|
||||
150
vendor/github.com/uptrace/bun/dialect/pgdialect/dialect.go
generated
vendored
Normal file
150
vendor/github.com/uptrace/bun/dialect/pgdialect/dialect.go
generated
vendored
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
package pgdialect
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/uptrace/bun/dialect"
|
||||
"github.com/uptrace/bun/dialect/feature"
|
||||
"github.com/uptrace/bun/dialect/sqltype"
|
||||
"github.com/uptrace/bun/schema"
|
||||
)
|
||||
|
||||
type Dialect struct {
|
||||
tables *schema.Tables
|
||||
features feature.Feature
|
||||
|
||||
appenderMap sync.Map
|
||||
scannerMap sync.Map
|
||||
}
|
||||
|
||||
func New() *Dialect {
|
||||
d := new(Dialect)
|
||||
d.tables = schema.NewTables(d)
|
||||
d.features = feature.Returning |
|
||||
feature.DefaultPlaceholder |
|
||||
feature.DoubleColonCast |
|
||||
feature.InsertTableAlias |
|
||||
feature.DeleteTableAlias |
|
||||
feature.TableCascade |
|
||||
feature.TableIdentity |
|
||||
feature.TableTruncate
|
||||
return d
|
||||
}
|
||||
|
||||
func (d *Dialect) Init(*sql.DB) {}
|
||||
|
||||
func (d *Dialect) Name() dialect.Name {
|
||||
return dialect.PG
|
||||
}
|
||||
|
||||
func (d *Dialect) Features() feature.Feature {
|
||||
return d.features
|
||||
}
|
||||
|
||||
func (d *Dialect) Tables() *schema.Tables {
|
||||
return d.tables
|
||||
}
|
||||
|
||||
func (d *Dialect) OnTable(table *schema.Table) {
|
||||
for _, field := range table.FieldMap {
|
||||
d.onField(field)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Dialect) onField(field *schema.Field) {
|
||||
field.DiscoveredSQLType = fieldSQLType(field)
|
||||
|
||||
if field.AutoIncrement {
|
||||
switch field.DiscoveredSQLType {
|
||||
case sqltype.SmallInt:
|
||||
field.CreateTableSQLType = pgTypeSmallSerial
|
||||
case sqltype.Integer:
|
||||
field.CreateTableSQLType = pgTypeSerial
|
||||
case sqltype.BigInt:
|
||||
field.CreateTableSQLType = pgTypeBigSerial
|
||||
}
|
||||
}
|
||||
|
||||
if field.Tag.HasOption("array") {
|
||||
field.Append = arrayAppender(field.IndirectType)
|
||||
field.Scan = arrayScanner(field.IndirectType)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Dialect) IdentQuote() byte {
|
||||
return '"'
|
||||
}
|
||||
|
||||
func (d *Dialect) Append(fmter schema.Formatter, b []byte, v interface{}) []byte {
|
||||
switch v := v.(type) {
|
||||
case nil:
|
||||
return dialect.AppendNull(b)
|
||||
case bool:
|
||||
return dialect.AppendBool(b, v)
|
||||
case int:
|
||||
return strconv.AppendInt(b, int64(v), 10)
|
||||
case int32:
|
||||
return strconv.AppendInt(b, int64(v), 10)
|
||||
case int64:
|
||||
return strconv.AppendInt(b, v, 10)
|
||||
case uint:
|
||||
return strconv.AppendInt(b, int64(v), 10)
|
||||
case uint32:
|
||||
return strconv.AppendInt(b, int64(v), 10)
|
||||
case uint64:
|
||||
return strconv.AppendInt(b, int64(v), 10)
|
||||
case float32:
|
||||
return dialect.AppendFloat32(b, v)
|
||||
case float64:
|
||||
return dialect.AppendFloat64(b, v)
|
||||
case string:
|
||||
return dialect.AppendString(b, v)
|
||||
case time.Time:
|
||||
return dialect.AppendTime(b, v)
|
||||
case []byte:
|
||||
return dialect.AppendBytes(b, v)
|
||||
case schema.QueryAppender:
|
||||
return schema.AppendQueryAppender(fmter, b, v)
|
||||
default:
|
||||
vv := reflect.ValueOf(v)
|
||||
if vv.Kind() == reflect.Ptr && vv.IsNil() {
|
||||
return dialect.AppendNull(b)
|
||||
}
|
||||
appender := d.Appender(vv.Type())
|
||||
return appender(fmter, b, vv)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Dialect) Appender(typ reflect.Type) schema.AppenderFunc {
|
||||
if v, ok := d.appenderMap.Load(typ); ok {
|
||||
return v.(schema.AppenderFunc)
|
||||
}
|
||||
|
||||
fn := schema.Appender(typ, customAppender)
|
||||
|
||||
if v, ok := d.appenderMap.LoadOrStore(typ, fn); ok {
|
||||
return v.(schema.AppenderFunc)
|
||||
}
|
||||
return fn
|
||||
}
|
||||
|
||||
func (d *Dialect) FieldAppender(field *schema.Field) schema.AppenderFunc {
|
||||
return schema.FieldAppender(d, field)
|
||||
}
|
||||
|
||||
func (d *Dialect) Scanner(typ reflect.Type) schema.ScannerFunc {
|
||||
if v, ok := d.scannerMap.Load(typ); ok {
|
||||
return v.(schema.ScannerFunc)
|
||||
}
|
||||
|
||||
fn := scanner(typ)
|
||||
|
||||
if v, ok := d.scannerMap.LoadOrStore(typ, fn); ok {
|
||||
return v.(schema.ScannerFunc)
|
||||
}
|
||||
return fn
|
||||
}
|
||||
7
vendor/github.com/uptrace/bun/dialect/pgdialect/go.mod
generated
vendored
Normal file
7
vendor/github.com/uptrace/bun/dialect/pgdialect/go.mod
generated
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
module github.com/uptrace/bun/dialect/pgdialect
|
||||
|
||||
go 1.16
|
||||
|
||||
replace github.com/uptrace/bun => ../..
|
||||
|
||||
require github.com/uptrace/bun v0.4.3
|
||||
22
vendor/github.com/uptrace/bun/dialect/pgdialect/go.sum
generated
vendored
Normal file
22
vendor/github.com/uptrace/bun/dialect/pgdialect/go.sum
generated
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo=
|
||||
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs=
|
||||
github.com/vmihailenco/msgpack/v5 v5.3.4 h1:qMKAwOV+meBw2Y8k9cVwAy7qErtYCwBzZ2ellBfvnqc=
|
||||
github.com/vmihailenco/msgpack/v5 v5.3.4/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 h1:RqytpXGR1iVNX7psjB3ff8y7sNFinVFvkx1c8SjBkio=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
11
vendor/github.com/uptrace/bun/dialect/pgdialect/safe.go
generated
vendored
Normal file
11
vendor/github.com/uptrace/bun/dialect/pgdialect/safe.go
generated
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// +build appengine
|
||||
|
||||
package pgdialect
|
||||
|
||||
func bytesToString(b []byte) string {
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func stringToBytes(s string) []byte {
|
||||
return []byte(s)
|
||||
}
|
||||
28
vendor/github.com/uptrace/bun/dialect/pgdialect/scan.go
generated
vendored
Normal file
28
vendor/github.com/uptrace/bun/dialect/pgdialect/scan.go
generated
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
package pgdialect
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/uptrace/bun/schema"
|
||||
)
|
||||
|
||||
func scanner(typ reflect.Type) schema.ScannerFunc {
|
||||
if typ.Kind() == reflect.Interface {
|
||||
return scanInterface
|
||||
}
|
||||
return schema.Scanner(typ)
|
||||
}
|
||||
|
||||
func scanInterface(dest reflect.Value, src interface{}) error {
|
||||
if dest.IsNil() {
|
||||
dest.Set(reflect.ValueOf(src))
|
||||
return nil
|
||||
}
|
||||
|
||||
dest = dest.Elem()
|
||||
if fn := scanner(dest.Type()); fn != nil {
|
||||
return fn(dest, src)
|
||||
}
|
||||
return fmt.Errorf("bun: can't scan %#v into %s", src, dest.Type())
|
||||
}
|
||||
104
vendor/github.com/uptrace/bun/dialect/pgdialect/sqltype.go
generated
vendored
Normal file
104
vendor/github.com/uptrace/bun/dialect/pgdialect/sqltype.go
generated
vendored
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
package pgdialect
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/uptrace/bun/dialect/sqltype"
|
||||
"github.com/uptrace/bun/schema"
|
||||
)
|
||||
|
||||
const (
|
||||
// Date / Time
|
||||
pgTypeTimestampTz = "TIMESTAMPTZ" // Timestamp with a time zone
|
||||
pgTypeDate = "DATE" // Date
|
||||
pgTypeTime = "TIME" // Time without a time zone
|
||||
pgTypeTimeTz = "TIME WITH TIME ZONE" // Time with a time zone
|
||||
pgTypeInterval = "INTERVAL" // Time Interval
|
||||
|
||||
// Network Addresses
|
||||
pgTypeInet = "INET" // IPv4 or IPv6 hosts and networks
|
||||
pgTypeCidr = "CIDR" // IPv4 or IPv6 networks
|
||||
pgTypeMacaddr = "MACADDR" // MAC addresses
|
||||
|
||||
// Serial Types
|
||||
pgTypeSmallSerial = "SMALLSERIAL" // 2 byte autoincrementing integer
|
||||
pgTypeSerial = "SERIAL" // 4 byte autoincrementing integer
|
||||
pgTypeBigSerial = "BIGSERIAL" // 8 byte autoincrementing integer
|
||||
|
||||
// Character Types
|
||||
pgTypeChar = "CHAR" // fixed length string (blank padded)
|
||||
pgTypeText = "TEXT" // variable length string without limit
|
||||
|
||||
// JSON Types
|
||||
pgTypeJSON = "JSON" // text representation of json data
|
||||
pgTypeJSONB = "JSONB" // binary representation of json data
|
||||
|
||||
// Binary Data Types
|
||||
pgTypeBytea = "BYTEA" // binary string
|
||||
)
|
||||
|
||||
var (
|
||||
timeType = reflect.TypeOf((*time.Time)(nil)).Elem()
|
||||
ipType = reflect.TypeOf((*net.IP)(nil)).Elem()
|
||||
ipNetType = reflect.TypeOf((*net.IPNet)(nil)).Elem()
|
||||
jsonRawMessageType = reflect.TypeOf((*json.RawMessage)(nil)).Elem()
|
||||
)
|
||||
|
||||
func fieldSQLType(field *schema.Field) string {
|
||||
if field.UserSQLType != "" {
|
||||
return field.UserSQLType
|
||||
}
|
||||
|
||||
if v, ok := field.Tag.Options["composite"]; ok {
|
||||
return v
|
||||
}
|
||||
|
||||
if _, ok := field.Tag.Options["hstore"]; ok {
|
||||
return "hstore"
|
||||
}
|
||||
|
||||
if _, ok := field.Tag.Options["array"]; ok {
|
||||
switch field.IndirectType.Kind() {
|
||||
case reflect.Slice, reflect.Array:
|
||||
sqlType := sqlType(field.IndirectType.Elem())
|
||||
return sqlType + "[]"
|
||||
}
|
||||
}
|
||||
|
||||
return sqlType(field.IndirectType)
|
||||
}
|
||||
|
||||
func sqlType(typ reflect.Type) string {
|
||||
switch typ {
|
||||
case ipType:
|
||||
return pgTypeInet
|
||||
case ipNetType:
|
||||
return pgTypeCidr
|
||||
case jsonRawMessageType:
|
||||
return pgTypeJSONB
|
||||
}
|
||||
|
||||
sqlType := schema.DiscoverSQLType(typ)
|
||||
switch sqlType {
|
||||
case sqltype.Timestamp:
|
||||
sqlType = pgTypeTimestampTz
|
||||
}
|
||||
|
||||
switch typ.Kind() {
|
||||
case reflect.Map, reflect.Struct:
|
||||
if sqlType == sqltype.VarChar {
|
||||
return pgTypeJSONB
|
||||
}
|
||||
return sqlType
|
||||
case reflect.Array, reflect.Slice:
|
||||
if typ.Elem().Kind() == reflect.Uint8 {
|
||||
return pgTypeBytea
|
||||
}
|
||||
return pgTypeJSONB
|
||||
}
|
||||
|
||||
return sqlType
|
||||
}
|
||||
18
vendor/github.com/uptrace/bun/dialect/pgdialect/unsafe.go
generated
vendored
Normal file
18
vendor/github.com/uptrace/bun/dialect/pgdialect/unsafe.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
// +build !appengine
|
||||
|
||||
package pgdialect
|
||||
|
||||
import "unsafe"
|
||||
|
||||
func bytesToString(b []byte) string {
|
||||
return *(*string)(unsafe.Pointer(&b))
|
||||
}
|
||||
|
||||
func stringToBytes(s string) []byte {
|
||||
return *(*[]byte)(unsafe.Pointer(
|
||||
&struct {
|
||||
string
|
||||
Cap int
|
||||
}{s, len(s)},
|
||||
))
|
||||
}
|
||||
14
vendor/github.com/uptrace/bun/dialect/sqltype/sqltype.go
generated
vendored
Normal file
14
vendor/github.com/uptrace/bun/dialect/sqltype/sqltype.go
generated
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
package sqltype
|
||||
|
||||
const (
|
||||
Boolean = "BOOLEAN"
|
||||
SmallInt = "SMALLINT"
|
||||
Integer = "INTEGER"
|
||||
BigInt = "BIGINT"
|
||||
Real = "REAL"
|
||||
DoublePrecision = "DOUBLE PRECISION"
|
||||
VarChar = "VARCHAR"
|
||||
Timestamp = "TIMESTAMP"
|
||||
JSON = "JSON"
|
||||
JSONB = "JSONB"
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue