diff options
Diffstat (limited to 'vendor/github.com/uptrace/bun/dialect/pgdialect')
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) } |