summaryrefslogtreecommitdiff
path: root/vendor/github.com/uptrace/bun/dialect
diff options
context:
space:
mode:
authorLibravatar tobi <31960611+tsmethurst@users.noreply.github.com>2021-08-25 15:34:33 +0200
committerLibravatar GitHub <noreply@github.com>2021-08-25 15:34:33 +0200
commit2dc9fc1626507bb54417fc4a1920b847cafb27a2 (patch)
tree4ddeac479b923db38090aac8bd9209f3646851c1 /vendor/github.com/uptrace/bun/dialect
parentManually approves followers (#146) (diff)
downloadgotosocial-2dc9fc1626507bb54417fc4a1920b847cafb27a2.tar.xz
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
Diffstat (limited to 'vendor/github.com/uptrace/bun/dialect')
-rw-r--r--vendor/github.com/uptrace/bun/dialect/append.go178
-rw-r--r--vendor/github.com/uptrace/bun/dialect/dialect.go26
-rw-r--r--vendor/github.com/uptrace/bun/dialect/feature/feature.go22
-rw-r--r--vendor/github.com/uptrace/bun/dialect/pgdialect/LICENSE24
-rw-r--r--vendor/github.com/uptrace/bun/dialect/pgdialect/append.go303
-rw-r--r--vendor/github.com/uptrace/bun/dialect/pgdialect/array.go65
-rw-r--r--vendor/github.com/uptrace/bun/dialect/pgdialect/array_parser.go146
-rw-r--r--vendor/github.com/uptrace/bun/dialect/pgdialect/array_scan.go302
-rw-r--r--vendor/github.com/uptrace/bun/dialect/pgdialect/dialect.go150
-rw-r--r--vendor/github.com/uptrace/bun/dialect/pgdialect/go.mod7
-rw-r--r--vendor/github.com/uptrace/bun/dialect/pgdialect/go.sum22
-rw-r--r--vendor/github.com/uptrace/bun/dialect/pgdialect/safe.go11
-rw-r--r--vendor/github.com/uptrace/bun/dialect/pgdialect/scan.go28
-rw-r--r--vendor/github.com/uptrace/bun/dialect/pgdialect/sqltype.go104
-rw-r--r--vendor/github.com/uptrace/bun/dialect/pgdialect/unsafe.go18
-rw-r--r--vendor/github.com/uptrace/bun/dialect/sqltype/sqltype.go14
16 files changed, 1420 insertions, 0 deletions
diff --git a/vendor/github.com/uptrace/bun/dialect/append.go b/vendor/github.com/uptrace/bun/dialect/append.go
new file mode 100644
index 000000000..7040c5155
--- /dev/null
+++ b/vendor/github.com/uptrace/bun/dialect/append.go
@@ -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
+}
diff --git a/vendor/github.com/uptrace/bun/dialect/dialect.go b/vendor/github.com/uptrace/bun/dialect/dialect.go
new file mode 100644
index 000000000..9ff8b2461
--- /dev/null
+++ b/vendor/github.com/uptrace/bun/dialect/dialect.go
@@ -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
+)
diff --git a/vendor/github.com/uptrace/bun/dialect/feature/feature.go b/vendor/github.com/uptrace/bun/dialect/feature/feature.go
new file mode 100644
index 000000000..ff8f1d625
--- /dev/null
+++ b/vendor/github.com/uptrace/bun/dialect/feature/feature.go
@@ -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
+)
diff --git a/vendor/github.com/uptrace/bun/dialect/pgdialect/LICENSE b/vendor/github.com/uptrace/bun/dialect/pgdialect/LICENSE
new file mode 100644
index 000000000..7ec81810c
--- /dev/null
+++ b/vendor/github.com/uptrace/bun/dialect/pgdialect/LICENSE
@@ -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.
diff --git a/vendor/github.com/uptrace/bun/dialect/pgdialect/append.go b/vendor/github.com/uptrace/bun/dialect/pgdialect/append.go
new file mode 100644
index 000000000..475621197
--- /dev/null
+++ b/vendor/github.com/uptrace/bun/dialect/pgdialect/append.go
@@ -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
+}
diff --git a/vendor/github.com/uptrace/bun/dialect/pgdialect/array.go b/vendor/github.com/uptrace/bun/dialect/pgdialect/array.go
new file mode 100644
index 000000000..57f5a4384
--- /dev/null
+++ b/vendor/github.com/uptrace/bun/dialect/pgdialect/array.go
@@ -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
+}
diff --git a/vendor/github.com/uptrace/bun/dialect/pgdialect/array_parser.go b/vendor/github.com/uptrace/bun/dialect/pgdialect/array_parser.go
new file mode 100644
index 000000000..1c927fca0
--- /dev/null
+++ b/vendor/github.com/uptrace/bun/dialect/pgdialect/array_parser.go
@@ -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++
+}
diff --git a/vendor/github.com/uptrace/bun/dialect/pgdialect/array_scan.go b/vendor/github.com/uptrace/bun/dialect/pgdialect/array_scan.go
new file mode 100644
index 000000000..33d31f325
--- /dev/null
+++ b/vendor/github.com/uptrace/bun/dialect/pgdialect/array_scan.go
@@ -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)
+ }
+}
diff --git a/vendor/github.com/uptrace/bun/dialect/pgdialect/dialect.go b/vendor/github.com/uptrace/bun/dialect/pgdialect/dialect.go
new file mode 100644
index 000000000..fb210751b
--- /dev/null
+++ b/vendor/github.com/uptrace/bun/dialect/pgdialect/dialect.go
@@ -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
+}
diff --git a/vendor/github.com/uptrace/bun/dialect/pgdialect/go.mod b/vendor/github.com/uptrace/bun/dialect/pgdialect/go.mod
new file mode 100644
index 000000000..0cad1ce5b
--- /dev/null
+++ b/vendor/github.com/uptrace/bun/dialect/pgdialect/go.mod
@@ -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
diff --git a/vendor/github.com/uptrace/bun/dialect/pgdialect/go.sum b/vendor/github.com/uptrace/bun/dialect/pgdialect/go.sum
new file mode 100644
index 000000000..4d0f1c1bb
--- /dev/null
+++ b/vendor/github.com/uptrace/bun/dialect/pgdialect/go.sum
@@ -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=
diff --git a/vendor/github.com/uptrace/bun/dialect/pgdialect/safe.go b/vendor/github.com/uptrace/bun/dialect/pgdialect/safe.go
new file mode 100644
index 000000000..dff30b9c5
--- /dev/null
+++ b/vendor/github.com/uptrace/bun/dialect/pgdialect/safe.go
@@ -0,0 +1,11 @@
+// +build appengine
+
+package pgdialect
+
+func bytesToString(b []byte) string {
+ return string(b)
+}
+
+func stringToBytes(s string) []byte {
+ return []byte(s)
+}
diff --git a/vendor/github.com/uptrace/bun/dialect/pgdialect/scan.go b/vendor/github.com/uptrace/bun/dialect/pgdialect/scan.go
new file mode 100644
index 000000000..9e22282f5
--- /dev/null
+++ b/vendor/github.com/uptrace/bun/dialect/pgdialect/scan.go
@@ -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())
+}
diff --git a/vendor/github.com/uptrace/bun/dialect/pgdialect/sqltype.go b/vendor/github.com/uptrace/bun/dialect/pgdialect/sqltype.go
new file mode 100644
index 000000000..4c2d8075d
--- /dev/null
+++ b/vendor/github.com/uptrace/bun/dialect/pgdialect/sqltype.go
@@ -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
+}
diff --git a/vendor/github.com/uptrace/bun/dialect/pgdialect/unsafe.go b/vendor/github.com/uptrace/bun/dialect/pgdialect/unsafe.go
new file mode 100644
index 000000000..2a02a20b1
--- /dev/null
+++ b/vendor/github.com/uptrace/bun/dialect/pgdialect/unsafe.go
@@ -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)},
+ ))
+}
diff --git a/vendor/github.com/uptrace/bun/dialect/sqltype/sqltype.go b/vendor/github.com/uptrace/bun/dialect/sqltype/sqltype.go
new file mode 100644
index 000000000..84a51d26d
--- /dev/null
+++ b/vendor/github.com/uptrace/bun/dialect/sqltype/sqltype.go
@@ -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"
+)