summaryrefslogtreecommitdiff
path: root/vendor/github.com/uptrace/bun/dialect/pgdialect
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/uptrace/bun/dialect/pgdialect')
-rw-r--r--vendor/github.com/uptrace/bun/dialect/pgdialect/append.go78
-rw-r--r--vendor/github.com/uptrace/bun/dialect/pgdialect/array.go2
-rw-r--r--vendor/github.com/uptrace/bun/dialect/pgdialect/array_parser.go19
-rw-r--r--vendor/github.com/uptrace/bun/dialect/pgdialect/dialect.go82
-rw-r--r--vendor/github.com/uptrace/bun/dialect/pgdialect/sqltype.go4
5 files changed, 75 insertions, 110 deletions
diff --git a/vendor/github.com/uptrace/bun/dialect/pgdialect/append.go b/vendor/github.com/uptrace/bun/dialect/pgdialect/append.go
index e8480b6be..d5e0d0a57 100644
--- a/vendor/github.com/uptrace/bun/dialect/pgdialect/append.go
+++ b/vendor/github.com/uptrace/bun/dialect/pgdialect/append.go
@@ -2,6 +2,7 @@ package pgdialect
import (
"database/sql/driver"
+ "encoding/hex"
"fmt"
"reflect"
"strconv"
@@ -28,26 +29,6 @@ var (
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:
@@ -57,31 +38,25 @@ func arrayAppend(fmter schema.Formatter, b []byte, v interface{}) []byte {
case bool:
return dialect.AppendBool(b, v)
case []byte:
- return dialect.AppendBytes(b, v)
+ return arrayAppendBytes(b, v)
case string:
return arrayAppendString(b, v)
case time.Time:
- return dialect.AppendTime(b, v)
+ return fmter.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 arrayAppendBytesValue(fmter schema.Formatter, b []byte, v reflect.Value) []byte {
+ return arrayAppendBytes(b, v.Bytes())
+}
+
func arrayAppendDriverValue(fmter schema.Formatter, b []byte, v reflect.Value) []byte {
iface, err := v.Interface().(driver.Valuer).Value()
if err != nil {
@@ -92,12 +67,12 @@ func arrayAppendDriverValue(fmter schema.Formatter, b []byte, v reflect.Value) [
//------------------------------------------------------------------------------
-func arrayAppender(typ reflect.Type) schema.AppenderFunc {
+func (d *Dialect) arrayAppender(typ reflect.Type) schema.AppenderFunc {
kind := typ.Kind()
switch kind {
case reflect.Ptr:
- if fn := arrayAppender(typ.Elem()); fn != nil {
+ if fn := d.arrayAppender(typ.Elem()); fn != nil {
return schema.PtrAppender(fn)
}
case reflect.Slice, reflect.Array:
@@ -121,7 +96,7 @@ func arrayAppender(typ reflect.Type) schema.AppenderFunc {
}
}
- appendElem := arrayElemAppender(elemType)
+ appendElem := d.arrayElemAppender(elemType)
if appendElem == nil {
panic(fmt.Errorf("pgdialect: %s is not supported", typ))
}
@@ -159,6 +134,21 @@ func arrayAppender(typ reflect.Type) schema.AppenderFunc {
}
}
+func (d *Dialect) arrayElemAppender(typ reflect.Type) schema.AppenderFunc {
+ if typ.Implements(driverValuerType) {
+ return arrayAppendDriverValue
+ }
+ switch typ.Kind() {
+ case reflect.String:
+ return arrayAppendStringValue
+ case reflect.Slice:
+ if typ.Elem().Kind() == reflect.Uint8 {
+ return arrayAppendBytesValue
+ }
+ }
+ return schema.Appender(d, typ)
+}
+
func appendStringSliceValue(fmter schema.Formatter, b []byte, v reflect.Value) []byte {
ss := v.Convert(sliceStringType).Interface().([]string)
return appendStringSlice(b, ss)
@@ -273,6 +263,22 @@ func appendFloat64Slice(b []byte, floats []float64) []byte {
//------------------------------------------------------------------------------
+func arrayAppendBytes(b []byte, bs []byte) []byte {
+ if bs == nil {
+ return dialect.AppendNull(b)
+ }
+
+ b = append(b, `"\\x`...)
+
+ s := len(b)
+ b = append(b, make([]byte, hex.EncodedLen(len(bs)))...)
+ hex.Encode(b[s:], bs)
+
+ b = append(b, '"')
+
+ return b
+}
+
func arrayAppendString(b []byte, s string) []byte {
b = append(b, '"')
for _, r := range s {
@@ -280,7 +286,7 @@ func arrayAppendString(b []byte, s string) []byte {
case 0:
// ignore
case '\'':
- b = append(b, "'''"...)
+ b = append(b, "''"...)
case '"':
b = append(b, '\\', '"')
case '\\':
diff --git a/vendor/github.com/uptrace/bun/dialect/pgdialect/array.go b/vendor/github.com/uptrace/bun/dialect/pgdialect/array.go
index 57f5a4384..281cff733 100644
--- a/vendor/github.com/uptrace/bun/dialect/pgdialect/array.go
+++ b/vendor/github.com/uptrace/bun/dialect/pgdialect/array.go
@@ -30,7 +30,7 @@ func Array(vi interface{}) *ArrayValue {
return &ArrayValue{
v: v,
- append: arrayAppender(v.Type()),
+ append: pgDialect.arrayAppender(v.Type()),
scan: arrayScanner(v.Type()),
}
}
diff --git a/vendor/github.com/uptrace/bun/dialect/pgdialect/array_parser.go b/vendor/github.com/uptrace/bun/dialect/pgdialect/array_parser.go
index 1c927fca0..0dff754f8 100644
--- a/vendor/github.com/uptrace/bun/dialect/pgdialect/array_parser.go
+++ b/vendor/github.com/uptrace/bun/dialect/pgdialect/array_parser.go
@@ -2,6 +2,7 @@ package pgdialect
import (
"bytes"
+ "encoding/hex"
"fmt"
"io"
)
@@ -109,11 +110,29 @@ func (p *arrayParser) readSubstring() ([]byte, error) {
}
continue
}
+ if c == '\'' && next == '\'' {
+ p.buf = append(p.buf, next)
+ c, err = p.readByte()
+ if err != nil {
+ return nil, err
+ }
+ continue
+ }
p.buf = append(p.buf, c)
c = next
}
+ if bytes.HasPrefix(p.buf, []byte("\\x")) && len(p.buf)%2 == 0 {
+ data := p.buf[2:]
+ buf := make([]byte, hex.DecodedLen(len(data)))
+ n, err := hex.Decode(buf, data)
+ if err != nil {
+ return nil, err
+ }
+ return buf[:n], nil
+ }
+
return p.buf, nil
}
diff --git a/vendor/github.com/uptrace/bun/dialect/pgdialect/dialect.go b/vendor/github.com/uptrace/bun/dialect/pgdialect/dialect.go
index 837c2d8ab..bac38972f 100644
--- a/vendor/github.com/uptrace/bun/dialect/pgdialect/dialect.go
+++ b/vendor/github.com/uptrace/bun/dialect/pgdialect/dialect.go
@@ -2,10 +2,7 @@ package pgdialect
import (
"database/sql"
- "reflect"
"strconv"
- "sync"
- "time"
"github.com/uptrace/bun/dialect"
"github.com/uptrace/bun/dialect/feature"
@@ -13,12 +10,13 @@ import (
"github.com/uptrace/bun/schema"
)
+var pgDialect = New()
+
type Dialect struct {
+ schema.BaseDialect
+
tables *schema.Tables
features feature.Feature
-
- appenderMap sync.Map
- scannerMap sync.Map
}
func New() *Dialect {
@@ -71,7 +69,7 @@ func (d *Dialect) onField(field *schema.Field) {
}
if field.Tag.HasOption("array") {
- field.Append = arrayAppender(field.StructField.Type)
+ field.Append = d.arrayAppender(field.StructField.Type)
field.Scan = arrayScanner(field.StructField.Type)
}
}
@@ -80,72 +78,10 @@ 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) AppendUint32(b []byte, n uint32) []byte {
+ return strconv.AppendInt(b, int64(int32(n)), 10)
}
-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
+func (d *Dialect) AppendUint64(b []byte, n uint64) []byte {
+ return strconv.AppendInt(b, int64(n), 10)
}
diff --git a/vendor/github.com/uptrace/bun/dialect/pgdialect/sqltype.go b/vendor/github.com/uptrace/bun/dialect/pgdialect/sqltype.go
index 4c2d8075d..dab0446ed 100644
--- a/vendor/github.com/uptrace/bun/dialect/pgdialect/sqltype.go
+++ b/vendor/github.com/uptrace/bun/dialect/pgdialect/sqltype.go
@@ -68,6 +68,10 @@ func fieldSQLType(field *schema.Field) string {
}
}
+ if field.DiscoveredSQLType == sqltype.Blob {
+ return pgTypeBytea
+ }
+
return sqlType(field.IndirectType)
}